Author: alink
Date: Tue Jul  8 00:21:26 2008
New Revision: 27830

URL: http://svn.gna.org/viewcvs/wesnoth?rev=27830&view=rev
Log:
Fix an old (1.2) but serious pathfinding bug with the replay/MP code:
It didn't use the same pathfinding solution as the local UI.
This gave visually different moves, and in worst case scenario, causes enemy to
pass through your invisible units (other player didn't really took this path)
This also activate the new smart pathfinding features for replay moves and is
much faster (~10x often more)

Modified:
    trunk/src/replay.cpp

Modified: trunk/src/replay.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/replay.cpp?rev=27830&r1=27829&r2=27830&view=diff
==============================================================================
--- trunk/src/replay.cpp (original)
+++ trunk/src/replay.cpp Tue Jul  8 00:21:26 2008
@@ -1059,33 +1059,41 @@
                                replay::throw_error(errbuf.str());
                        }
 
-                       const bool teleport = 
u->second.get_ability_bool("teleport",u->first);
-
-                       paths 
paths_list(map,units,src,teams,false,teleport,current_team);
-
-                       std::map<gamemap::location,paths::route>::iterator rt = 
paths_list.routes.find(dst);
-                       if(rt == paths_list.routes.end()) {
-
+                       // search path assuming current_team as viewing team
+                       const shortest_path_calculator calc(u->second, 
current_team, units, teams, map);
+                       std::set<gamemap::location> allowed_teleports;
+                       if(u->second.get_ability_bool("teleport",src)) {
+                               // search all known empty friendly villages
+                               for(std::set<gamemap::location>::const_iterator 
i = current_team.villages().begin();
+                                       i != current_team.villages().end(); 
++i) {
+                                       if 
(current_team.is_enemy(u->second.side()) && current_team.fogged(*i))
+                                               continue;
+
+                                       unit_map::const_iterator occupant = 
find_visible_unit(units, *i, map,teams, current_team);
+                                       if (occupant != units.end() && occupant 
!= u)
+                                               continue;
+
+                                       allowed_teleports.insert(*i);
+                               }
+                       }
+
+                       paths::route route = a_star_search(src, dst, 10000.0, 
&calc, map.w(), map.h(), &allowed_teleports);
+
+                       if(route.steps.empty()) {
                                std::stringstream errbuf;
-                               for(rt = paths_list.routes.begin(); rt != 
paths_list.routes.end(); ++rt) {
-                                       errbuf << "can get to: " << rt->first 
<< '\n';
-                               }
-
-                               errbuf << "src cannot get to dst: " << 
u->second.movement_left() << ' '
-                                      << paths_list.routes.size() << ' ' << 
src << " -> " << dst << '\n';
+                               errbuf << "src cannot get to dst: " << src << " 
-> " << dst
+                                      << " with " << u->second.movement_left() 
<< " MP left\n";
                                replay::throw_error(errbuf.str());
                        }
 
-                       rt->second.steps.push_back(dst);
-
                        if(!get_replay_source().is_skipping()) {
-                               
unit_display::move_unit(rt->second.steps,u->second,teams);
+                               
unit_display::move_unit(route.steps,u->second,teams);
                        }
                        else{
                                //unit location needs to be updated
-                               u->second.set_goto(*(rt->second.steps.end() - 
1));
-                       }
-                       u->second.set_movement(rt->second.move_left);
+                               u->second.set_goto(*(route.steps.end() - 1));
+                       }
+                       u->second.set_movement(route.move_left);
 
                        std::pair<gamemap::location,unit> *up = 
units.extract(u->first);
                        up->first = dst;


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to