2424#include " AIModule.h"
2525#include " Map.h"
2626#include " Camera.h"
27+ #include " Projectile.h"
2728#include " ../Savegame/SavedGame.h"
2829#include " ../Savegame/SavedBattleGame.h"
2930#include " ExplosionBState.h"
@@ -2411,35 +2412,39 @@ int TileEngine::calculateParabola(Position origin, Position target, bool storeTr
24112412 int z = origin.z ;
24122413 int i = 8 ;
24132414 int result = V_EMPTY ;
2414- std::vector<Position> _trajectory;
24152415 Position lastPosition = Position (x,y,z);
24162416 Position nextPosition = lastPosition;
2417+
2418+ if (storeTrajectory && trajectory)
2419+ {
2420+ // initla value for small hack to glue `calculateLine` into one continuous arc
2421+ trajectory->push_back (lastPosition);
2422+ }
24172423 while (z > 0 )
24182424 {
24192425 x = (int )((double )origin.x + (double )i * cos (te) * sin (fi));
24202426 y = (int )((double )origin.y + (double )i * sin (te) * sin (fi));
24212427 z = (int )((double )origin.z + (double )i * cos (fi) - zK * ((double )i - ro / 2.0 ) * ((double )i - ro / 2.0 ) + zA);
24222428 // passes through this point?
24232429 nextPosition = Position (x,y,z);
2424- _trajectory.clear ();
2425- result = calculateLine (lastPosition, nextPosition, false , 0 , excludeUnit);
2426- if (result != V_EMPTY )
2430+
2431+ if (storeTrajectory && trajectory)
24272432 {
2428- result = calculateLine (lastPosition, nextPosition, true , &_trajectory, excludeUnit);
2429- nextPosition = _trajectory.back (); // pick the INSIDE position of impact
2430- break ;
2433+ // remove end point of previus trajectory part, becasue next one will add this point again
2434+ trajectory->pop_back ();
24312435 }
2432- if (storeTrajectory && trajectory)
2436+ result = calculateLine (lastPosition, nextPosition, storeTrajectory, storeTrajectory ? trajectory : 0 , excludeUnit);
2437+ if (result != V_EMPTY )
24332438 {
2434- trajectory->push_back (nextPosition);
2439+ if (!storeTrajectory && trajectory)
2440+ {
2441+ result = calculateLine (lastPosition, nextPosition, false , trajectory, excludeUnit); // pick the INSIDE position of impact
2442+ }
2443+ break ;
24352444 }
24362445 lastPosition = nextPosition;
24372446 ++i;
24382447 }
2439- if (trajectory != 0 )
2440- { // store the position of impact
2441- trajectory->push_back (nextPosition);
2442- }
24432448 return result;
24442449}
24452450
@@ -2930,13 +2935,19 @@ bool TileEngine::validateThrow(BattleAction &action, Position originVoxel, Posit
29302935 return false ;
29312936 }
29322937
2938+ std::vector<Position> trajectory;
2939+ // thows should be around 10 tiles far, make one allocation that fit 99% cases with some margin
2940+ trajectory.resize (16 *20 );
29332941 // we try 8 different curvatures to try and reach our goal.
29342942 int test = V_OUTOFBOUNDS ;
29352943 while (!foundCurve && curvature < 5.0 )
29362944 {
2937- std::vector<Position> trajectory;
2938- test = calculateParabola (originVoxel, targetVoxel, false , &trajectory, action.actor , curvature, Position (0 ,0 ,0 ));
2939- Position tilePos = ((trajectory.at (0 ) + Position (0 ,0 ,1 )) / Position (16 , 16 , 24 ));
2945+ trajectory.clear ();
2946+ test = calculateParabola (originVoxel, targetVoxel, true , &trajectory, action.actor , curvature, Position (0 ,0 ,0 ));
2947+ // position that item hit
2948+ Position hitPos = (trajectory.back () + Position (0 ,0 ,1 )) / Position (16 , 16 , 24 );
2949+ // position where item will land
2950+ Position tilePos = ((trajectory.at (trajectory.size () + Projectile::ItemDropVoxelOffset - 1 )) / Position (16 , 16 , 24 ));
29402951 if (forced || (test != V_OUTOFBOUNDS && tilePos == targetPos))
29412952 {
29422953 if (voxelType)
@@ -2950,7 +2961,7 @@ bool TileEngine::validateThrow(BattleAction &action, Position originVoxel, Posit
29502961 curvature += 0.5 ;
29512962 if (test != V_OUTOFBOUNDS && action.actor ->getFaction () == FACTION_PLAYER ) // obstacle indicator is only for player
29522963 {
2953- Tile* hitTile = _save->getTile (tilePos );
2964+ Tile* hitTile = _save->getTile (hitPos );
29542965 if (hitTile)
29552966 {
29562967 hitTile->setObstacle (test);
0 commit comments