Merge of fendrin's new teleport and tunnel code.
The changes are guarded by the C++ and WML conditional symbol "EXPERIMENTAL". The experimental flag is temporarily defaulted off, so those patches should have no effect on people doing ordinary builds. This may change once fendrin has the tunnel code fixed and polished.
This commit is contained in:
parent
51d12123c5
commit
75925deb82
29 changed files with 439 additions and 5 deletions
|
@ -39,8 +39,9 @@ except KeyError:
|
|||
# Build-control options
|
||||
#
|
||||
|
||||
# Experimental code is enabled by default in unstable (odd minor version).
|
||||
experimental_default = (int(version.split(".")[1]) % 2) == 1
|
||||
# FIXME: Experimental code enabled by default in unstable (odd minor version).
|
||||
#experimental_default = (int(version.split(".")[1]) % 2) == 1
|
||||
experimental_default = False
|
||||
|
||||
opts = Variables('.scons-option-cache')
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ AC_PREREQ([2.60])
|
|||
# to match whether this is a stable or unstable release.
|
||||
#######################################################################
|
||||
define([WESNOTH_VERSION],[1.7.12+svn])
|
||||
experimental_default=yes
|
||||
experimental_default=no
|
||||
define([WESNOTH_BUGS],[http://bugs.wesnoth.org])
|
||||
|
||||
AC_INIT([Battle for Wesnoth], WESNOTH_VERSION, WESNOTH_BUGS, [wesnoth])
|
||||
|
|
|
@ -379,6 +379,35 @@ Any units adjacent to this unit will fight as if it were dusk when it is night,
|
|||
female_name= _ "female^teleport"
|
||||
description= _ "Teleport:
|
||||
This unit may teleport between any two empty villages owned by its side using one of its moves."
|
||||
#ifdef EXPERIMENTAL
|
||||
[tunnel]
|
||||
id=village_teleport
|
||||
[source]
|
||||
terrain=*^V*
|
||||
owner_side=$teleport_unit.side
|
||||
[not]
|
||||
[filter]
|
||||
[not]
|
||||
id=$teleport_unit.id
|
||||
[/not]
|
||||
[/filter]
|
||||
[/not]
|
||||
[/source]
|
||||
|
||||
[target]
|
||||
terrain=*^V*
|
||||
owner_side=$teleport_unit.side
|
||||
[not]
|
||||
[filter]
|
||||
[/filter]
|
||||
[/not]
|
||||
[/target]
|
||||
|
||||
[filter]
|
||||
ability=teleport
|
||||
[/filter]
|
||||
[/tunnel]
|
||||
#endif
|
||||
[/teleport]
|
||||
#enddef
|
||||
|
||||
|
|
|
@ -155,6 +155,82 @@ Xu , Xu , Qxu , Qxu , Ql , Ql
|
|||
[/unit]
|
||||
[/side]
|
||||
|
||||
#ifdef EXPERIMENTAL
|
||||
[event]
|
||||
name=prestart
|
||||
{VARIABLE teleports_on no}
|
||||
[/event]
|
||||
[label]
|
||||
x,y=20,13
|
||||
text="Teleport switch"
|
||||
[/label]
|
||||
[event]
|
||||
name=moveto
|
||||
first_time_only=no
|
||||
[filter]
|
||||
x,y=20,13
|
||||
[/filter]
|
||||
|
||||
[if]
|
||||
[variable]
|
||||
name=teleports_on
|
||||
boolean_equals=no
|
||||
[/variable]
|
||||
[then]
|
||||
[tunnel]
|
||||
id="one"
|
||||
bidirectional=yes
|
||||
always_visible=yes
|
||||
[source]
|
||||
x=8
|
||||
y=6
|
||||
[/source]
|
||||
[target]
|
||||
x=20
|
||||
y=12
|
||||
[/target]
|
||||
[filter]
|
||||
[/filter]
|
||||
[/tunnel]
|
||||
[tunnel]
|
||||
id="two"
|
||||
bidirectional=no
|
||||
[source]
|
||||
x=20
|
||||
y=14
|
||||
[/source]
|
||||
[target]
|
||||
x=21
|
||||
y=4
|
||||
[/target]
|
||||
[filter]
|
||||
[/filter]
|
||||
[/tunnel]
|
||||
{VARIABLE teleports_on yes}
|
||||
[message]
|
||||
speaker=narrator
|
||||
icon=wesnoth-icon.png
|
||||
message="Teleporters activated"
|
||||
[/message]
|
||||
[/then]
|
||||
[else]
|
||||
[tunnel]
|
||||
id="one,two"
|
||||
remove=yes
|
||||
[/tunnel]
|
||||
{VARIABLE teleports_on no}
|
||||
[message]
|
||||
speaker=narrator
|
||||
icon=wesnoth-icon.png
|
||||
message="Teleporters deactivated"
|
||||
[/message]
|
||||
[/else]
|
||||
[/if]
|
||||
[/event]
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
[side]
|
||||
type=Orcish Warlord
|
||||
id="Urug-Telfar"
|
||||
|
@ -191,6 +267,16 @@ Xu , Xu , Qxu , Qxu , Ql , Ql
|
|||
[/object]
|
||||
[/modifications]
|
||||
[/unit]
|
||||
#ifdef EXPERIMENTAL
|
||||
[village]
|
||||
x,y=26,5
|
||||
[/village]
|
||||
[unit]
|
||||
x,y=24,7
|
||||
type="Silver Mage"
|
||||
name= _ "Hidden Teleporter"
|
||||
[/unit]
|
||||
#endif
|
||||
[/side]
|
||||
[side]
|
||||
side=3
|
||||
|
@ -900,6 +986,7 @@ For game purposes, the races group into factions; for example, orcs often cooper
|
|||
[/event]
|
||||
|
||||
[item]
|
||||
#ifndef EXPERIMENTAL
|
||||
x,y=9,1
|
||||
# This doesn't work, image doesn't do animation
|
||||
image="scenery/fire1.png~CS(0,0,50):150,scenery/fire2.png~CS(0,0,50):150,scenery/fire3.png~CS(0,0,50):150,scenery/fire4.png~CS(0,0,50):150,scenery/fire5.png~CS(0,0,50):150,scenery/fire6.png~CS(0,0,50):150,scenery/fire7.png~CS(0,0,50):150,scenery/fire8.png~CS(0,0,50):150"
|
||||
|
@ -910,6 +997,7 @@ For game purposes, the races group into factions; for example, orcs often cooper
|
|||
[/item]
|
||||
|
||||
[item]
|
||||
#endif
|
||||
x,y=8,8
|
||||
image="items/orcish-flag.png"
|
||||
[/item]
|
||||
|
|
|
@ -341,6 +341,10 @@ set(wesnoth-main_SRC
|
|||
multiplayer_create.cpp
|
||||
network.cpp
|
||||
network_worker.cpp
|
||||
#ifdef EXPERIMENTAL
|
||||
pathfind/pathfind.cpp
|
||||
pathfind/teleport.cpp
|
||||
#endif
|
||||
playcampaign.cpp
|
||||
play_controller.cpp
|
||||
playmp_controller.cpp
|
||||
|
@ -434,7 +438,9 @@ SET(libwesnoth-game_STAT_SRC
|
|||
marked-up_text.cpp
|
||||
minimap.cpp
|
||||
pathfind/astarsearch.cpp
|
||||
#ifndef EXPERIMENTAL
|
||||
pathfind/pathfind.cpp
|
||||
#endif
|
||||
pathutils.cpp
|
||||
preferences.cpp
|
||||
preferences_display.cpp
|
||||
|
|
|
@ -224,6 +224,9 @@ wesnoth_source = \
|
|||
network.cpp \
|
||||
network_worker.cpp \
|
||||
pathfind/pathfind.cpp \
|
||||
#ifdef EXPERIMENTAL
|
||||
pathfind/teleport.cpp \
|
||||
#endif
|
||||
playcampaign.cpp \
|
||||
play_controller.cpp \
|
||||
playmp_controller.cpp \
|
||||
|
|
|
@ -219,6 +219,7 @@ wesnoth_sources = Split("""
|
|||
multiplayer_create.cpp
|
||||
multiplayer_connect.cpp
|
||||
pathfind/pathfind.cpp
|
||||
pathfind/teleport.cpp
|
||||
playcampaign.cpp
|
||||
play_controller.cpp
|
||||
playmp_controller.cpp
|
||||
|
|
|
@ -407,8 +407,12 @@ bool move_result::test_route(const unit &un, const team &my_team, const unit_map
|
|||
}
|
||||
const pathfind::shortest_path_calculator calc(un, my_team, units, teams,map);
|
||||
|
||||
#ifndef EXPERIMENTAL
|
||||
//allowed teleports
|
||||
std::set<map_location> allowed_teleports = pathfind::get_teleport_locations(un, units, my_team, true);//@todo 1.9: see_all -> false
|
||||
#else
|
||||
pathfind::teleport_map allowed_teleports = pathfind::get_teleport_locations(un, units, my_team, true);//@todo 1.9: see_all -> false
|
||||
#endif
|
||||
|
||||
//do an A*-search
|
||||
route_ = pathfind::a_star_search(un.get_location(), to_, 10000.0, &calc, map.w(), map.h(), &allowed_teleports);
|
||||
|
@ -505,7 +509,11 @@ void move_result::do_execute()
|
|||
if (from_ != to_) {
|
||||
move_unit(
|
||||
/*move_unit_spectator* move_spectator*/ &move_spectator_,
|
||||
#ifndef EXPERIMENTAL
|
||||
/*std::vector<map_location> route*/ route_.steps,
|
||||
#else
|
||||
/*std::vector<map_location> pathfind::route*/ route_.steps,
|
||||
#endif
|
||||
/*replay* move_recorder*/ &recorder,
|
||||
/*undo_list* undo_stack*/ NULL,
|
||||
/*bool show_move*/ preferences::show_ai_moves(),
|
||||
|
|
|
@ -335,10 +335,16 @@ void readonly_context_impl::calculate_moves(const unit_map& units, std::map<map_
|
|||
srcdst.insert(trivial_mv);
|
||||
dstsrc.insert(trivial_mv);
|
||||
}
|
||||
#ifndef EXPERIMENTAL
|
||||
bool teleports = un_it->second.get_ability_bool("teleport");
|
||||
#endif
|
||||
res.insert(std::pair<map_location,pathfind::paths>(
|
||||
un_it->first,pathfind::paths(get_info().map,units,
|
||||
#ifndef EXPERIMENTAL
|
||||
un_it->first,get_info().teams,false,teleports,
|
||||
#else
|
||||
un_it->first,get_info().teams,false,true,
|
||||
#endif
|
||||
current_team(),0,see_all)));
|
||||
}
|
||||
|
||||
|
@ -906,7 +912,11 @@ bool readonly_context_impl::leader_can_reach_keep() const
|
|||
}
|
||||
|
||||
// Find where the leader can move
|
||||
#ifndef EXPERIMENTAL
|
||||
const pathfind::paths leader_paths(get_info().map,get_info().units,leader->first,get_info().teams,false,false,current_team());
|
||||
#else
|
||||
const pathfind::paths leader_paths(get_info().map,get_info().units,leader->first,get_info().teams,false,true,current_team());
|
||||
#endif
|
||||
|
||||
|
||||
return leader_paths.destinations.contains(start_pos);
|
||||
|
|
|
@ -527,7 +527,11 @@ bool ai_default::multistep_move_possible(const map_location& from,
|
|||
unit temp_unit(i->second);
|
||||
temp_unit.set_movement(itor->move_left);
|
||||
const temporary_unit_placer unit_placer(units_,via,temp_unit);
|
||||
#ifndef EXPERIMENTAL
|
||||
const pathfind::paths unit_paths(map_,units_,via,teams_,false,false,current_team());
|
||||
#else
|
||||
const pathfind::paths unit_paths(map_,units_,via,teams_,false,true,current_team());
|
||||
#endif
|
||||
|
||||
LOG_AI << "Found " << unit_paths.destinations.size() << " moves for temp leader.\n";
|
||||
|
||||
|
@ -1881,7 +1885,11 @@ void ai_default::move_leader_to_goals()
|
|||
}
|
||||
|
||||
const pathfind::paths leader_paths(map_, units_, leader->first,
|
||||
#ifndef EXPERIMENTAL
|
||||
teams_, false, false, current_team());
|
||||
#else
|
||||
teams_, false, true, current_team());
|
||||
#endif
|
||||
|
||||
std::map<map_location,pathfind::paths> possible_moves;
|
||||
possible_moves.insert(std::pair<map_location,pathfind::paths>(leader->first,leader_paths));
|
||||
|
@ -1918,7 +1926,11 @@ void ai_default::move_leader_after_recruit()
|
|||
const bool passive_leader = get_passive_leader()||passive_leader_shares_keep;
|
||||
|
||||
const pathfind::paths leader_paths(map_, units_, leader->first,
|
||||
#ifndef EXPERIMENTAL
|
||||
teams_, false, false, current_team());
|
||||
#else
|
||||
teams_, false, true, current_team());
|
||||
#endif
|
||||
|
||||
std::map<map_location,pathfind::paths> possible_moves;
|
||||
possible_moves.insert(std::pair<map_location,pathfind::paths>(leader->first,leader_paths));
|
||||
|
@ -1954,7 +1966,11 @@ void ai_default::move_leader_after_recruit()
|
|||
unit_map temp_units;
|
||||
temp_units.add(current_loc, leader->second);
|
||||
const pathfind::paths p(map_, temp_units, current_loc, teams_, false,
|
||||
#ifndef EXPERIMENTAL
|
||||
false, current_team());
|
||||
#else
|
||||
true, current_team());
|
||||
#endif
|
||||
|
||||
if (p.destinations.contains(i->first))
|
||||
{
|
||||
|
|
|
@ -124,7 +124,11 @@ bool default_ai_context_impl::multistep_move_possible(const map_location& from,
|
|||
unit temp_unit(i->second);
|
||||
temp_unit.set_movement(itor->move_left);
|
||||
const temporary_unit_placer unit_placer(units_,via,temp_unit);
|
||||
#ifndef EXPERIMENTAL
|
||||
const pathfind::paths unit_paths(get_info().map,units_,via,get_info().teams,false,false,current_team());
|
||||
#else
|
||||
const pathfind::paths unit_paths(get_info().map,units_,via,get_info().teams,false,true,current_team());
|
||||
#endif
|
||||
|
||||
LOG_AI << "Found " << unit_paths.destinations.size() << " moves for temp leader.\n";
|
||||
|
||||
|
|
|
@ -733,7 +733,11 @@ void ai_default::move_leader_to_keep()
|
|||
|
||||
// Find where the leader can move
|
||||
const pathfind::paths leader_paths(map_, units_, leader->first,
|
||||
#ifndef EXPERIMENTAL
|
||||
teams_, false, false, current_team());
|
||||
#else
|
||||
teams_, false, true, current_team());
|
||||
#endif
|
||||
const map_location& keep = suitable_keep(leader->first,leader_paths);
|
||||
|
||||
std::map<map_location,pathfind::paths> possible_moves;
|
||||
|
|
|
@ -177,7 +177,11 @@ variant formula_ai::make_action(game_logic::const_formula_ptr formula_, const ga
|
|||
|
||||
pathfind::plain_route formula_ai::shortest_path_calculator(const map_location &src,
|
||||
const map_location &dst, unit_map::iterator &unit_it,
|
||||
#ifndef EXPERIMENTAL
|
||||
std::set<map_location> & allowed_teleports) const
|
||||
#else
|
||||
pathfind::teleport_map& allowed_teleports) const
|
||||
#endif
|
||||
{
|
||||
map_location destination = dst;
|
||||
|
||||
|
@ -229,7 +233,11 @@ pathfind::plain_route formula_ai::shortest_path_calculator(const map_location &s
|
|||
return route;
|
||||
}
|
||||
|
||||
#ifndef EXPERIMENTAL
|
||||
std::set<map_location> formula_ai::get_allowed_teleports(unit_map::iterator& unit_it) const
|
||||
#else
|
||||
pathfind::teleport_map formula_ai::get_allowed_teleports(unit_map::iterator& unit_it) const
|
||||
#endif
|
||||
{
|
||||
return pathfind::get_teleport_locations(unit_it->second, get_info().units, current_team(), true);
|
||||
}
|
||||
|
@ -242,7 +250,11 @@ map_location formula_ai::path_calculator(const map_location& src, const map_loca
|
|||
//check if destination is within unit's reach, if not, calculate where to move
|
||||
if (!path->second.destinations.contains(dst))
|
||||
{
|
||||
#ifndef EXPERIMENTAL
|
||||
std::set<map_location> allowed_teleports = get_allowed_teleports(unit_it);
|
||||
#else
|
||||
pathfind::teleport_map allowed_teleports = get_allowed_teleports(unit_it);
|
||||
#endif
|
||||
//destination is too far, check where unit can go
|
||||
pathfind::plain_route route = shortest_path_calculator( src, dst, unit_it, allowed_teleports );
|
||||
|
||||
|
|
|
@ -104,8 +104,13 @@ public:
|
|||
void handle_exception(game_logic::formula_error& e) const;
|
||||
void handle_exception(game_logic::formula_error& e, const std::string& failed_operation) const;
|
||||
|
||||
#ifndef EXPERIMENTAL
|
||||
std::set<map_location> get_allowed_teleports(unit_map::iterator& unit_it) const;
|
||||
pathfind::plain_route shortest_path_calculator(const map_location& src, const map_location& dst, unit_map::iterator& unit_it, std::set<map_location>& allowed_teleports) const;
|
||||
#else
|
||||
pathfind::teleport_map get_allowed_teleports(unit_map::iterator& unit_it) const;
|
||||
pathfind::plain_route shortest_path_calculator(const map_location& src, const map_location& dst, unit_map::iterator& unit_it, pathfind::teleport_map& allowed_teleports) const;
|
||||
#endif
|
||||
|
||||
void store_outcome_position(const variant& var);
|
||||
|
||||
|
|
|
@ -658,7 +658,11 @@ private:
|
|||
if (ai_.get_info().units.find(loc)==ai_.get_info().units.end()){
|
||||
return variant();
|
||||
}
|
||||
#ifndef EXPERIMENTAL
|
||||
const pathfind::paths unit_paths(ai_.get_info().map, ai_.get_info().units, loc ,ai_.get_info().teams, false, false, ai_.current_team());
|
||||
#else
|
||||
const pathfind::paths unit_paths(ai_.get_info().map, ai_.get_info().units, loc ,ai_.get_info().teams, false, true, ai_.current_team());
|
||||
#endif
|
||||
return variant(new location_callable(ai_.suitable_keep(loc,unit_paths)));
|
||||
}
|
||||
|
||||
|
@ -972,7 +976,11 @@ private:
|
|||
throw formula_error( str.str(), "", "", 0);
|
||||
}
|
||||
|
||||
#ifndef EXPERIMENTAL
|
||||
std::set<map_location> allowed_teleports = ai_.get_allowed_teleports(unit_it);
|
||||
#else
|
||||
pathfind::teleport_map allowed_teleports = ai_.get_allowed_teleports(unit_it);
|
||||
#endif
|
||||
|
||||
pathfind::plain_route route = ai_.shortest_path_calculator( src, dst, unit_it, allowed_teleports );
|
||||
|
||||
|
@ -1022,7 +1030,11 @@ private:
|
|||
throw formula_error( str.str(), "", "", 0);
|
||||
}
|
||||
|
||||
#ifndef EXPERIMENTAL
|
||||
std::set<map_location> allowed_teleports = ai_.get_allowed_teleports(unit_it);
|
||||
#else
|
||||
pathfind::teleport_map allowed_teleports = ai_.get_allowed_teleports(unit_it);
|
||||
#endif
|
||||
|
||||
pathfind::emergency_path_calculator em_calc(unit_it->second, ai_.get_info().map);
|
||||
|
||||
|
@ -1076,7 +1088,11 @@ private:
|
|||
throw formula_error( str.str(), "", "", 0);
|
||||
}
|
||||
|
||||
#ifndef EXPERIMENTAL
|
||||
std::set<map_location> allowed_teleports = ai_.get_allowed_teleports(unit_it);
|
||||
#else
|
||||
pathfind::teleport_map allowed_teleports = ai_.get_allowed_teleports(unit_it);
|
||||
#endif
|
||||
|
||||
pathfind::plain_route route = ai_.shortest_path_calculator( src, dst, unit_it, allowed_teleports );
|
||||
|
||||
|
@ -1316,11 +1332,15 @@ public:
|
|||
{}
|
||||
private:
|
||||
variant execute(const formula_callable& variables, formula_debugger *fdb) const {
|
||||
#ifndef EXPERIMENTAL
|
||||
variant loc_var = args()[0]->evaluate(variables,add_debug_info(fdb,0,"unit_at:location"));
|
||||
if (loc_var.is_null()) {
|
||||
return variant();
|
||||
}
|
||||
const location_callable* loc = convert_variant<location_callable>(loc_var);
|
||||
#else
|
||||
const location_callable* loc = convert_variant<location_callable>(args()[0]->evaluate(variables,add_debug_info(fdb,0,"unit_at:location")));
|
||||
#endif
|
||||
const unit_map::const_iterator i = ai_.get_info().units.find(loc->loc());
|
||||
if(i != ai_.get_info().units.end()) {
|
||||
return variant(new unit_callable(*i));
|
||||
|
|
|
@ -670,7 +670,11 @@ double move_leader_to_goals_phase::evaluate()
|
|||
}
|
||||
|
||||
const pathfind::paths leader_paths(get_info().map, get_info().units, leader->first,
|
||||
#ifndef EXPERIMENTAL
|
||||
get_info().teams, false, false, current_team());
|
||||
#else
|
||||
get_info().teams, false, true, current_team());
|
||||
#endif
|
||||
|
||||
std::map<map_location,pathfind::paths> possible_moves;
|
||||
possible_moves.insert(std::pair<map_location,pathfind::paths>(leader->first,leader_paths));
|
||||
|
@ -746,7 +750,11 @@ double move_leader_to_keep_phase::evaluate()
|
|||
|
||||
// Find where the leader can move
|
||||
const pathfind::paths leader_paths(get_info().map, units_, leader->first,
|
||||
#ifndef EXPERIMENTAL
|
||||
get_info().teams, false, false, current_team());
|
||||
#else
|
||||
get_info().teams, false, true, current_team());
|
||||
#endif
|
||||
const map_location& keep = suitable_keep(leader->first,leader_paths);
|
||||
|
||||
std::map<map_location,pathfind::paths> possible_moves;
|
||||
|
@ -1748,7 +1756,11 @@ double retreat_phase::evaluate()
|
|||
typedef move_map::const_iterator Itor;
|
||||
std::pair<Itor,Itor> itors = get_srcdst().equal_range(i->first);
|
||||
map_location best_pos, best_defensive(i->first);
|
||||
#ifndef EXPERIMENTAL
|
||||
double best_rating = -1000.0;
|
||||
#else
|
||||
double best_rating = 0.0;
|
||||
#endif
|
||||
int best_defensive_rating = i->second.defense_modifier(get_info().map.get_terrain(i->first))
|
||||
- (get_info().map.is_village(i->first) ? 10 : 0);
|
||||
while(itors.first != itors.second) {
|
||||
|
|
|
@ -622,6 +622,32 @@ WML_HANDLER_FUNCTION(place_shroud, /*event_info*/,cfg)
|
|||
toggle_shroud(false,cfg );
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL
|
||||
WML_HANDLER_FUNCTION(tunnel, /*event_info*/, cfg)
|
||||
{
|
||||
const bool remove = utils::string_bool(cfg["remove"], false);
|
||||
if (remove) {
|
||||
const std::vector<std::string> ids = utils::split(cfg["id"]);
|
||||
foreach(const std::string &id, ids) {
|
||||
resources::tunnels->remove(id);
|
||||
}
|
||||
} else if (cfg.get_children("source").empty() ||
|
||||
cfg.get_children("target").empty() ||
|
||||
cfg.get_children("filter").empty()) {
|
||||
ERR_WML << "[tunnel] is missing a mandatory tag:\n"
|
||||
<< cfg.get_config().debug();
|
||||
} else {
|
||||
pathfind::teleport_group tunnel(cfg, false);
|
||||
resources::tunnels->add(tunnel);
|
||||
|
||||
if (utils::string_bool(cfg["bidirectional"], true)) {
|
||||
tunnel = pathfind::teleport_group(cfg, true);
|
||||
resources::tunnels->add(tunnel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
WML_HANDLER_FUNCTION(teleport, event_info, cfg)
|
||||
{
|
||||
unit_map::iterator u = resources::units->find(event_info.loc1);
|
||||
|
@ -2107,10 +2133,14 @@ WML_HANDLER_FUNCTION(kill, event_info, cfg)
|
|||
}
|
||||
if(utils::string_bool(cfg["animate"])) {
|
||||
resources::screen->scroll_to_tile(loc);
|
||||
#ifndef EXPERIMENTAL
|
||||
if (un.valid()) {
|
||||
#endif
|
||||
unit_display::unit_die(loc, un->second);
|
||||
}
|
||||
#ifndef EXPERIMENTAL
|
||||
}
|
||||
#endif
|
||||
if (fire_event)
|
||||
{
|
||||
game_events::fire("die", death_loc, death_loc);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "serialization/parser.hpp"
|
||||
#include "util.hpp"
|
||||
#include "wml_exception.hpp"
|
||||
#include "foreach.hpp"
|
||||
|
||||
static lg::log_domain log_config("config");
|
||||
#define ERR_CF LOG_STREAM(err, log_config)
|
||||
|
|
|
@ -1256,9 +1256,15 @@ void menu_handler::show_enemy_moves(bool ignore_units, int side_num)
|
|||
!gui_->fogged(u->first) && !u->second.incapacitated() && !invisible)
|
||||
{
|
||||
const unit_movement_resetter move_reset(u->second);
|
||||
#ifndef EXPERIMENTAL
|
||||
bool teleports = u->second.get_ability_bool("teleport");
|
||||
#endif
|
||||
const pathfind::paths& path = pathfind::paths(map_,units_,
|
||||
#ifndef EXPERIMENTAL
|
||||
u->first,teams_,false,teleports,teams_[gui_->viewing_team()], 0,false, ignore_units);
|
||||
#else
|
||||
u->first,teams_,false,true,teams_[gui_->viewing_team()], 0,false, ignore_units);
|
||||
#endif
|
||||
|
||||
gui_->highlight_another_reach(path);
|
||||
}
|
||||
|
|
|
@ -232,9 +232,15 @@ void mouse_handler::mouse_motion(int x, int y, const bool browse, bool update)
|
|||
//unit under cursor is not on our team, highlight reach
|
||||
unit_movement_resetter move_reset(un->second);
|
||||
|
||||
#ifndef EXPERIMENTAL
|
||||
bool teleport = un->second.get_ability_bool("teleport");
|
||||
#endif
|
||||
current_paths_ = pathfind::paths(map_,units_,new_hex,teams_,
|
||||
#ifndef EXPERIMENTAL
|
||||
false,teleport,viewing_team(),path_turns_);
|
||||
#else
|
||||
false,true,viewing_team(),path_turns_);
|
||||
#endif
|
||||
gui().highlight_reach(current_paths_);
|
||||
enemy_paths_ = true;
|
||||
} else {
|
||||
|
@ -343,7 +349,11 @@ pathfind::marked_route mouse_handler::get_route(unit_map::const_iterator un, map
|
|||
// The pathfinder will check unit visibility (fogged/stealthy).
|
||||
const pathfind::shortest_path_calculator calc(un->second,team,units_,teams_,map_);
|
||||
|
||||
#ifndef EXPERIMENTAL
|
||||
std::set<map_location> allowed_teleports = pathfind::get_teleport_locations(
|
||||
#else
|
||||
pathfind::teleport_map allowed_teleports = pathfind::get_teleport_locations(
|
||||
#endif
|
||||
un->second, units_, viewing_team());
|
||||
|
||||
pathfind::plain_route route;
|
||||
|
@ -534,9 +544,15 @@ void mouse_handler::select_hex(const map_location& hex, const bool browse) {
|
|||
// if it's not the unit's turn, we reset its moves
|
||||
// and we restore them before the "select" event is raised
|
||||
unit_movement_resetter move_reset(u->second, u->second.side() != side_num_);
|
||||
#ifndef EXPERIMENTAL
|
||||
bool teleport = u->second.get_ability_bool("teleport");
|
||||
#endif
|
||||
current_paths_ = pathfind::paths(map_, units_, hex, teams_,
|
||||
#ifndef EXPERIMENTAL
|
||||
false, teleport, viewing_team(), path_turns_);
|
||||
#else
|
||||
false, true, viewing_team(), path_turns_);
|
||||
#endif
|
||||
}
|
||||
show_attack_options(u);
|
||||
gui().highlight_reach(current_paths_);
|
||||
|
|
|
@ -43,7 +43,11 @@ public:
|
|||
void cycle_back_units(const bool browse) { cycle_units(browse, true); }
|
||||
|
||||
int get_path_turns() const { return path_turns_; }
|
||||
#ifndef EXPERIMENTAL
|
||||
const pathfind::paths& current_paths() const { return current_paths_; }
|
||||
#else
|
||||
const pathfind::paths get_current_paths() const { return current_paths_; }
|
||||
#endif
|
||||
const map_location& get_last_hex() const { return last_hex_; }
|
||||
map_location get_selected_hex() const { return selected_hex_; }
|
||||
bool get_undo() const { return undo_; }
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
#include "log.hpp"
|
||||
#include "map.hpp"
|
||||
#include "pathfind/pathfind.hpp"
|
||||
#ifdef EXPERIMENTAL
|
||||
#include "pathfind/teleport.hpp"
|
||||
#endif
|
||||
#include "foreach.hpp"
|
||||
|
||||
#include <queue>
|
||||
|
@ -78,9 +81,14 @@ struct node {
|
|||
, in(bad_search_counter)
|
||||
{
|
||||
}
|
||||
#ifndef EXPERIMENTAL
|
||||
node(double s, const map_location &c, const map_location &p, const map_location &dst, bool i, const std::set<map_location>* teleports):
|
||||
#else
|
||||
node(double s, const map_location &c, const map_location &p, const map_location &dst, bool i, const pathfind::teleport_map* teleports):
|
||||
#endif
|
||||
g(s), h(heuristic(c, dst)), t(g + h), curr(c), prev(p), in(search_counter + i)
|
||||
{
|
||||
#ifndef EXPERIMENTAL
|
||||
if (teleports != NULL) {
|
||||
double srch = h, dsth = h;
|
||||
std::set<map_location>::const_iterator i;
|
||||
|
@ -92,10 +100,40 @@ struct node {
|
|||
}
|
||||
if(new_dsth < dsth) {
|
||||
dsth = new_dsth;
|
||||
#else
|
||||
if (teleports && !teleports->empty()) {
|
||||
|
||||
double new_srch = 1.0;
|
||||
std::set<map_location> sources;
|
||||
teleports->get_sources(sources);
|
||||
|
||||
std::set<map_location>::const_iterator it = sources.begin();
|
||||
for(; it != sources.end(); ++it) {
|
||||
const double tmp_srch = heuristic(c, *it);
|
||||
if (tmp_srch < new_srch) { new_srch = tmp_srch; }
|
||||
#endif
|
||||
}
|
||||
#ifdef EXPERIMENTAL
|
||||
|
||||
|
||||
double new_dsth = 1.0;
|
||||
std::set<map_location> targets;
|
||||
teleports->get_targets(targets);
|
||||
|
||||
for(it = targets.begin(); it != targets.end(); ++it) {
|
||||
const double tmp_dsth = heuristic(*it, dst);
|
||||
if (tmp_dsth < new_dsth) { new_dsth = tmp_dsth; }
|
||||
#endif
|
||||
}
|
||||
#ifndef EXPERIMENTAL
|
||||
if(srch + dsth + 1.0 < h) {
|
||||
h = srch + dsth + 1.0;
|
||||
#else
|
||||
|
||||
double new_h = new_srch + new_dsth + 1.0;
|
||||
if (new_h < h) {
|
||||
h = new_h;
|
||||
#endif
|
||||
t = g + h;
|
||||
}
|
||||
}
|
||||
|
@ -129,8 +167,14 @@ public:
|
|||
|
||||
|
||||
pathfind::plain_route pathfind::a_star_search(const map_location& src, const map_location& dst,
|
||||
#ifndef EXPERIMENTAL
|
||||
double stop_at, const pathfind::cost_calculator *calc, const size_t width,
|
||||
const size_t height, const std::set<map_location>* teleports) {
|
||||
#else
|
||||
double stop_at, const cost_calculator *calc, const size_t width,
|
||||
const size_t height,
|
||||
const teleport_map *teleports) {
|
||||
#endif
|
||||
//----------------- PRE_CONDITIONS ------------------
|
||||
assert(src.valid(width, height));
|
||||
assert(dst.valid(width, height));
|
||||
|
@ -147,6 +191,7 @@ pathfind::plain_route pathfind::a_star_search(const map_location& src, const map
|
|||
return locRoute;
|
||||
}
|
||||
|
||||
#ifndef EXPERIMENTAL
|
||||
if (teleports && teleports->empty()) teleports = NULL;
|
||||
|
||||
std::vector<map_location> locs(teleports ? 6 + teleports->size() : 6 );
|
||||
|
@ -154,6 +199,7 @@ pathfind::plain_route pathfind::a_star_search(const map_location& src, const map
|
|||
std::copy(teleports->begin(), teleports->end(), locs.begin() + 6);
|
||||
}
|
||||
|
||||
#endif
|
||||
// increment search_counter but skip the range equivalent to uninitialized
|
||||
search_counter += 2;
|
||||
if (search_counter - bad_search_counter <= 1u)
|
||||
|
@ -181,12 +227,35 @@ pathfind::plain_route pathfind::a_star_search(const map_location& src, const map
|
|||
|
||||
if (n.t >= nodes[index(dst)].g) break;
|
||||
|
||||
#ifdef EXPERIMENTAL
|
||||
std::vector<map_location> locs;
|
||||
|
||||
int i;
|
||||
if (teleports && !teleports->empty()) {
|
||||
|
||||
std::set<map_location> allowed_teleports;
|
||||
teleports->get_adjacents(allowed_teleports, n.curr);
|
||||
|
||||
i = allowed_teleports.size() +6;
|
||||
locs = std::vector<map_location>(i);
|
||||
|
||||
std::copy(allowed_teleports.begin(), allowed_teleports.end(), locs.begin() + 6);
|
||||
} else
|
||||
{ locs = std::vector<map_location>(6); i = 6;}
|
||||
|
||||
#endif
|
||||
get_adjacent_tiles(n.curr, &locs[0]);
|
||||
|
||||
#ifndef EXPERIMENTAL
|
||||
int i = teleports && teleports->count(n.curr) ? locs.size() : 6;
|
||||
#endif
|
||||
for (; i-- > 0;) {
|
||||
if (!locs[i].valid(width, height)) continue;
|
||||
#ifndef EXPERIMENTAL
|
||||
|
||||
#else
|
||||
if (locs[i] == n.curr) continue;
|
||||
#endif
|
||||
node& next = nodes[index(locs[i])];
|
||||
|
||||
double thresh = (next.in - search_counter <= 1u) ? next.g : stop_at;
|
||||
|
|
|
@ -104,6 +104,7 @@ bool pathfind::enemy_zoc(unit_map const &units, std::vector<team> const &teams,
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifndef EXPERIMENTAL
|
||||
std::set<map_location> pathfind::get_teleport_locations(const unit &u,
|
||||
const unit_map &units, const team &viewing_team,
|
||||
bool see_all, bool ignore_units)
|
||||
|
@ -127,6 +128,7 @@ std::set<map_location> pathfind::get_teleport_locations(const unit &u,
|
|||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
static unsigned search_counter;
|
||||
|
||||
namespace {
|
||||
|
@ -193,16 +195,22 @@ static void find_routes(const gamemap& map, const unit_map& units,
|
|||
bool see_all, bool ignore_units)
|
||||
{
|
||||
const team& current_team = teams[u.side() - 1];
|
||||
#ifndef EXPERIMENTAL
|
||||
std::set<map_location> teleports;
|
||||
#else
|
||||
pathfind::teleport_map teleports;
|
||||
#endif
|
||||
if (allow_teleport) {
|
||||
teleports = pathfind::get_teleport_locations(u, units, viewing_team, see_all, ignore_units);
|
||||
}
|
||||
|
||||
const int total_movement = u.total_movement();
|
||||
|
||||
#ifndef EXPERIMENTAL
|
||||
std::vector<map_location> locs(6 + teleports.size());
|
||||
std::copy(teleports.begin(), teleports.end(), locs.begin() + 6);
|
||||
|
||||
#endif
|
||||
search_counter += 2;
|
||||
if (search_counter == 0) search_counter = 2;
|
||||
|
||||
|
@ -224,10 +232,24 @@ static void find_routes(const gamemap& map, const unit_map& units,
|
|||
pq.pop_back();
|
||||
n.in = search_counter;
|
||||
|
||||
#ifdef EXPERIMENTAL
|
||||
std::set<map_location> allowed_teleports;
|
||||
teleports.get_adjacents(allowed_teleports, n.curr);
|
||||
std::vector<map_location> locs(6 + allowed_teleports.size());
|
||||
std::copy(allowed_teleports.begin(), allowed_teleports.end(), locs.begin() + 6);
|
||||
#endif
|
||||
get_adjacent_tiles(n.curr, &locs[0]);
|
||||
#ifndef EXPERIMENTAL
|
||||
for (int i = teleports.count(n.curr) ? locs.size() : 6; i-- > 0; ) {
|
||||
#else
|
||||
for (int i = locs.size(); i-- > 0; ) {
|
||||
#endif
|
||||
if (!locs[i].valid(map.w(), map.h())) continue;
|
||||
|
||||
#ifdef EXPERIMENTAL
|
||||
if (locs[i] == n.curr) continue;
|
||||
|
||||
#endif
|
||||
node& next = nodes[index(locs[i])];
|
||||
|
||||
bool next_visited = next.in - search_counter <= 1u;
|
||||
|
|
|
@ -26,6 +26,9 @@ class unit_movement_type;
|
|||
|
||||
#include "map_location.hpp"
|
||||
#include "team.hpp"
|
||||
#ifdef EXPERIMENTAL
|
||||
#include "pathfind/teleport.hpp"
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
@ -35,6 +38,10 @@ class unit_movement_type;
|
|||
|
||||
namespace pathfind {
|
||||
|
||||
#ifdef EXPERIMENTAL
|
||||
class teleport_map;
|
||||
|
||||
#endif
|
||||
enum VACANT_TILE_TYPE { VACANT_CASTLE, VACANT_ANY };
|
||||
|
||||
/**
|
||||
|
@ -53,10 +60,12 @@ bool enemy_zoc(unit_map const &units,
|
|||
std::vector<team> const &teams, map_location const &loc,
|
||||
team const &viewing_team, int side, bool see_all=false);
|
||||
|
||||
#ifndef EXPERIMENTAL
|
||||
std::set<map_location> get_teleport_locations(const unit &u,
|
||||
const unit_map &units, const team &viewing_team,
|
||||
bool see_all = false, bool ignore_units = false);
|
||||
|
||||
#endif
|
||||
struct cost_calculator
|
||||
{
|
||||
cost_calculator() {}
|
||||
|
@ -81,7 +90,11 @@ struct paths
|
|||
// Construct a list of paths for the unit at loc.
|
||||
// - force_ignore_zocs: find the path ignoring ZOC entirely,
|
||||
// if false, will use the unit on the loc's ability
|
||||
#ifndef EXPERIMENTAL
|
||||
// - allow_teleport: indicates whether unit teleports between villages
|
||||
#else
|
||||
// - allow_teleport: indicates whether the paths should include teleportation (false for sight)
|
||||
#endif
|
||||
// - additional_turns: if 0, paths for how far the unit can move this turn will be calculated.
|
||||
// If 1, paths for how far the unit can move by the end of next turn
|
||||
// will be calculated, and so forth.
|
||||
|
@ -146,9 +159,17 @@ struct plain_route
|
|||
};
|
||||
|
||||
plain_route a_star_search(map_location const &src, map_location const &dst,
|
||||
#ifndef EXPERIMENTAL
|
||||
double stop_at, cost_calculator const* costCalculator,
|
||||
#else
|
||||
double stop_at, const cost_calculator* costCalculator,
|
||||
#endif
|
||||
const size_t parWidth, const size_t parHeight,
|
||||
#ifndef EXPERIMENTAL
|
||||
std::set<map_location> const *teleports = NULL);
|
||||
#else
|
||||
const teleport_map* teleports = NULL);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Add marks on a route @a rt assuming that a @unit u travels along it.
|
||||
|
@ -214,7 +235,11 @@ struct dummy_path_calculator : cost_calculator
|
|||
virtual double cost(const map_location& loc, const double so_far) const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#ifndef EXPERIMENTAL
|
||||
|
||||
#endif
|
||||
}
|
||||
#ifndef EXPERIMENTAL
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -63,6 +63,9 @@ play_controller::play_controller(const config& level, game_state& state_of_game,
|
|||
menu_handler_(NULL, units_, teams_, level, map_, game_config, tod_manager_, state_of_game, undo_stack_, redo_stack_),
|
||||
soundsources_manager_(),
|
||||
tod_manager_(level, num_turns, &state_of_game),
|
||||
#ifdef EXPERIMENTAL
|
||||
pathfind_manager_(),
|
||||
#endif
|
||||
gui_(),
|
||||
statistics_context_(level["name"]),
|
||||
level_(level),
|
||||
|
@ -117,6 +120,9 @@ play_controller::~play_controller()
|
|||
resources::screen = NULL;
|
||||
resources::soundsources = NULL;
|
||||
resources::tod_manager = NULL;
|
||||
#ifdef EXPERIMENTAL
|
||||
resources::tunnels = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void play_controller::init(CVideo& video){
|
||||
|
@ -245,8 +251,14 @@ void play_controller::init_managers(){
|
|||
prefs_disp_manager_.reset(new preferences::display_manager(gui_.get()));
|
||||
tooltips_manager_.reset(new tooltips::manager(gui_->video()));
|
||||
soundsources_manager_.reset(new soundsource::manager(*gui_));
|
||||
#ifdef EXPERIMENTAL
|
||||
pathfind_manager_.reset(new pathfind::manager(level_));
|
||||
#endif
|
||||
|
||||
resources::soundsources = soundsources_manager_.get();
|
||||
#ifdef EXPERIMENTAL
|
||||
resources::tunnels = pathfind_manager_.get();
|
||||
#endif
|
||||
|
||||
halo_manager_.reset(new halo::manager(*gui_));
|
||||
LOG_NG << "done initializing managers... " << (SDL_GetTicks() - ticks_) << "\n";
|
||||
|
@ -611,6 +623,9 @@ config play_controller::to_config() const
|
|||
|
||||
//write out the current state of the map
|
||||
cfg["map_data"] = map_.write();
|
||||
#ifdef EXPERIMENTAL
|
||||
cfg.merge_with(pathfind_manager_->to_config());
|
||||
#endif
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
@ -897,15 +912,25 @@ void play_controller::process_keyup_event(const SDL_Event& event) {
|
|||
const unit_map::iterator u = mouse_handler_.selected_unit();
|
||||
|
||||
if(u != units_.end()) {
|
||||
#ifndef EXPERIMENTAL
|
||||
bool teleport = u->second.get_ability_bool("teleport");
|
||||
|
||||
#endif
|
||||
// if it's not the unit's turn, we reset its moves
|
||||
unit_movement_resetter move_reset(u->second, u->second.side() != player_number_);
|
||||
|
||||
mouse_handler_.set_current_paths(pathfind::paths(map_,units_,u->first,
|
||||
#ifndef EXPERIMENTAL
|
||||
teams_,false,teleport, teams_[gui_->viewing_team()],
|
||||
#else
|
||||
teams_,false,true, teams_[gui_->viewing_team()],
|
||||
#endif
|
||||
mouse_handler_.get_path_turns()));
|
||||
#ifndef EXPERIMENTAL
|
||||
gui_->highlight_reach(mouse_handler_.current_paths());
|
||||
#else
|
||||
gui_->highlight_reach(mouse_handler_.get_current_paths());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@ protected:
|
|||
events::menu_handler menu_handler_;
|
||||
boost::scoped_ptr<soundsource::manager> soundsources_manager_;
|
||||
tod_manager tod_manager_;
|
||||
#ifdef EXPERIMENTAL
|
||||
boost::scoped_ptr<pathfind::manager> pathfind_manager_;
|
||||
#endif
|
||||
|
||||
//other objects
|
||||
boost::scoped_ptr<game_display> gui_;
|
||||
|
|
|
@ -25,4 +25,7 @@ namespace resources
|
|||
LuaKernel *lua_kernel;
|
||||
play_controller *controller;
|
||||
::tod_manager *tod_manager;
|
||||
#ifdef EXPERIMENTAL
|
||||
pathfind::manager *tunnels;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -27,6 +27,9 @@ class tod_manager;
|
|||
class unit_map;
|
||||
|
||||
namespace soundsource { class manager; }
|
||||
#ifdef EXPERIMENTAL
|
||||
namespace pathfind { class manager; }
|
||||
#endif
|
||||
|
||||
namespace resources
|
||||
{
|
||||
|
@ -39,6 +42,9 @@ namespace resources
|
|||
extern LuaKernel *lua_kernel;
|
||||
extern play_controller *controller;
|
||||
extern tod_manager *tod_manager;
|
||||
#ifdef EXPERIMENTAL
|
||||
extern pathfind::manager *tunnels;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1549,12 +1549,17 @@ static int intf_find_path(lua_State *L)
|
|||
}
|
||||
|
||||
team &viewing_team = teams[viewing_side - 1];
|
||||
#ifndef EXPERIMENTAL
|
||||
std::set<map_location> teleport_locations;
|
||||
|
||||
if (!ignore_teleport) {
|
||||
teleport_locations = pathfind::get_teleport_locations(
|
||||
*u, units, viewing_team, see_all, ignore_units);
|
||||
}
|
||||
#else
|
||||
const pathfind::teleport_map teleport_locations = !ignore_teleport ? pathfind::get_teleport_locations(
|
||||
*u, units, viewing_team, see_all, ignore_units) : pathfind::teleport_map();
|
||||
#endif
|
||||
|
||||
if (!calc) {
|
||||
calc = new pathfind::shortest_path_calculator(*u, viewing_team,
|
||||
|
|
Loading…
Add table
Reference in a new issue