This is a strict refactor, all we do is move the functions and
variables used just for animations to "unit_animation_component",
and include the necessary headers appropriate.
With a bit more work we can probably remove the graphics related
headers from unit.hpp
drawable unit inherits from unit, and implements the draw function,
used only by the display. when the display wants to use the function,
it casts a unit pointer to a drawable_unit, and draws it. this
improves encapsulation.
Defines a UnitPtr (boost::intrusive_ptr<unit>, after irc
discussion), which the engine will use to pass units between
different modules, and which it is planned that the animation
engine will also hold, to avoid segfaulting.
Unfortunately this commit could not really be made smaller, it is
necessary to change all of these things over at once, or specify
very complicated deletion policies for the units at the
boundaries of the modules.
The main intention of the commit is to get these three modules
using a reference counting system to hold units, even as they
are passed between the modules. Eventually the fake units and
other kinds of units will all also be held in such pointers, and
the unit_map::unit_pod object will be replaced itself with a
single smart pointer.
Finally the animations objects will hold weak pointers to units,
to fix the segfault issues.
This commit required us to change over the whiteboard, most of
the action_wml, and the AI modules, since these make use of the
recall list from the team class.
We also add the unit_ptr.hpp header file, to allow to forward
declare the UnitPtr object essentially, and it's const variation.
If we forward declare the intrusive_ptr functions, we can forward
declare the UnitPtr type and avoid including unit in a bunch of
places that we don't need to. (Good as that is a very heavy
include.)
The declaration is now in unit_ptr.hpp
Since we can't forward declare inheritance, the easiest way to
resolve linker problems is to not derive unit from the
reference_counted_object class and just include the intrusive_ptr
boilerplate as usual instead.
This use of handle-body idiom saves *alot* of includes, since a
huge number of objects include unit indirectly, and make no use
of the ai formula features.
It turned out that alot of compilation units were using resources
but not including the header, and only getting circuitously
through the display.hpp header which got it from unit.hpp. This
is an improvement since unit itself doesn't need the header,
and most classes probably don't either.
The remaining uses are just, checking whether or not the pointer
is null, or resets to its value, or simply storing it in a local
variable.
It might be appropriate to add resources::game_map back as a
function taking no parameters, at least this is flexible
enough to be changed later easily.
This the result of executing, in folder src/, the following
find . -type f -exec sed -i 's/\*resources\:\:game_map/resources\:\:gameboard->map()/g' '{}' \;
and carefully inspecting the result.
We also had to add game_board.hpp includes in various places,
and change the arguent order of unit::is_visible_to_team --
this function was taking *resources::game_map as its default
argument, and we do not want to include game_board in unit.hpp,
as it creates cyclic dependencies. This was resolved by
eliminating this as a default value -- this is an improvement,
since usually when this function was called it was in a context
where a game_map was available already locally anyways.
This is the result of running, in src/ directory, the following:
find . -type f -exec sed -i 's/resources::game_map->/resources::gameboard->map()./g' '{}' \;
and carefully inspecting the result, and adding "game_board.hpp"
This commit makes the main unit animation accessor / mutator
functions applicable to const units, and makes the animation
state member variables mutable to allow this.
const'ed member functions:
set standning
idling
selecting
ghosted
disabed_ghosted
clear_haloes
refresh
invalidate
redraw
mutable member variables:
animation state enum
boost scoped pointer anim_ (can be reset in the redraw fcn)
next_idling_
frame_begin_time_
unit_halo_
refreshing_
draw_bars_
The purpose of this is to improve encapsulation of units, as now
we can use const units in the display functions, and reserve non-
const unit references for use in the game logic.
Putting a movement orb on an enemy petrified unit is rather
redundant, so this commit prevents that behavior. Statues owned
by the viewing team will still have orbs, which seems acceptable.
This is a refactor to introduce an object encapsulating the unit map, the game map, and the list of teams. Introducing this object permits us to move a substantial amount of code out of the play_controller object, and also to give a home to some helper functions in unit.?pp that previously sat in the global namespace. It also allows us to simplify the construction of some of the clients of play_controller.
This refactor is ongoing WIP. The goals are
(1) better organize the architecture of the engine, to make saving and reloading easier.
(2) Facilitate the introduction of an improved pathfinding mechanism, which will need to sit between most of the other engine modules and the unit map / game map.
(3) Refactoring clarifies what the existing code is doing, therefore it may help us to find bugs in the current system, which may be fixed independently of the refactor in 1.12.
Unit tested and playtested after moving the functions decalarations,
and definitions, adding links to play_controller::game_board from
resources.?pp, and executing find and replace commands:
git grep -lz 'find_visible_unit(' | xargs -0 perl -i'' -pE "s/find_visible_unit\(/resources::gameboard->find_visible_unit\(/g"
git grep -lz 'get_visible_unit(' | xargs -0 perl -i'' -pE "s/get_visible_unit\(/resources::gameboard->get_visible_unit\(/g"
Just wanted to remove the empty strings that got created:
find . -type f -exec sed -i 's/<< "" <</<</g' '{}' \;
find . -type f -exec sed -i 's/<<"" <</<</g' '{}' \;
I also unstaged tools/schema/tags.cpp, since I don't think I changed
that.
This is the result of running command, in src/,
find . -type f -exec sed -i 's/\(WRN.*\)\\n\"\;/\1\" << std::endl\;/g' '{}' \;
and inspecting the results.
Also ran this subsequently:
find . -type f -exec sed -i 's/\(WARN.*\)\\n\"\;/\1\" << std::endl\;/g' '{}' \;
which only affected render.cpp
we now enable warning 4800. I ran though the msvc compile with this
warning and i found some (in overlay.hpp, unit.cpp, whiteboard/move.cpp)
unintended implicit bool b = cfg["attributename"] casts that use
the implicit attribute_value to int cast and then a int to bool cast.
So for attributename=true b would be false. So i believe this
is a useful warning.
There are also a lot of implicit int to bool cast from the SDL and LUA
C-libraries which use int instead of bool because C doesn't have bool.
In this case this warning is less useful, but i still think it's worth
it since a "!= 0" or "== 1" isn't cost.
Plus if someone really wants to disable this warning he can still
disable it in the msvc project settings, while before is was not
possible for someone to enable this warning the the settings.
the plan is, that random_new::generator will be a object that does synced random calls during a synced context and otherwise not,
so that we cannot create OOS anymore by using random in unsynced actions like select event
the intention is also to unfy random calls for attacks and random calls and for other actions like traits and [set_variable] rand= .
the synced random generator will be set with the set_scontext_synced object.
the new rng will be similar to the old rng used for attacks becasue it will ask the server for a new seed for every new user action (=recruit, attack...) that requires random numbers.
Previously there were 2 different random generators, one for attacks, and one for other things, pr 121 is supposed to fix the problems with the "sending data over teh network first" an we try to throw the old rng for non attack things out. So that attacks and other tings use the same rng.
We use a new random generator which is automaticly synced during the execution of scned_context::run_in_scned_context, and otherwise not. So we cannot cause oos anymore by using rand= from an unsnced command like "select"
Alternativeley we can also set the new random synced by using the new RAII object set_sconext_sycned, this happens for example during prestart events.
Unlike the old random generator, the new random generator is not determinstic by default because it asks the server (or itself in a SP game) for a new seed, at every side command (attack, move, recruit ...) that requires random, similar to how the previous rand for attacks worked (it doesn't ask at the beginning, just the first time it is needed unlinke how attacks worked before). That way i can also use the same rng for attacks and for other random choices.
I also plan to move the code from set/get_random_results to syncec_checkup.cpp later.
this commit is part of pr 121.
Changed from cfg["foo"] > number, to !cfg["foo"].blank(). Turned a cfg call into
just a default assignment. Added a .to_int to a cfg["foo"] call to prepare
against bad user input. Finally added whitespace to 2 lines to get them to line
up with the rest of the lines.
Actually allows for the unit instance recall costs to be used. Proper
taking of the gold and undoing the cost for each unit is implemented
and works. At advancement if the unit's current recall matches their
unit_type's recall_cost then it takes the new unit_type's recall_cost
otherwise it keeps whatever value it currently has until it fails this
check. Recall costs are also now persistant and will carry over from
one scenario into the next as well.
If a cost is not set, it will continue to use the team/side/default
costs, these changes should not affect the current workings when
dealing with unaltered scenarios, and unit config files. I repeat This
will not affect or change the currently way things work UNLESS a user
alters a file or includes the new recall_cost (as in copies and
modifies a unit in the scenario unit files) for a unit instance in
their scenario file(s).
Add the variables, lua, and wml support variables to allow a scenario
designer the ability to define different from the standard recall costs
or team recall costs for both individual units and unit types.
from least to highest order of precendent we'll have default, team/side,
unit_type, and finally individual units.
The tag in the scenarios and in the unit config files is recall_cost=int.
in an earlier commit these tests were disabled because they were segfaulting
and blocking the test suite from running. the cause was obscure: the tests
were based on making a dummy unit type and inserting / reinserting it
into the unit_map. however, it turns out that in the current code, a freshly
constructed unit_type is not safe to be used to construct a unit. the reason
is that then it does not have any genders defined, so when the unit is built
it will not find any genders and fail with segfault, or even more bizarrely,
a division by zero error. i found that even running with gdb did not give
an actual line number, and simply said that the failure occurred in the
unit constructor, a function whose initalizer list spans several pages.
the correct fix is to invoke "unit_types.build_unit_type" on the unit type
before using it. this permits the unit tests to run.
additionally i added an assert to the generate_genders function in unit.cpp,
which surely should have been there in the first place.
Previously, the [filter_vision] tag would cause a false positive when a
unit was on terrain on which it was invisible and that also was under
fog/shroud. There might have been other combinations that did not work
either, I did not check that. I did check that all 8 combinations of
visble=yes/no, the unit hiding due to terrain or not, and the hex being
under fog/shroud or not work now.