Jump to content

chansey

Community Members
  • Posts

    7
  • Joined

  • Last visited

Posts posted by chansey

  1. When a ranged unit attack a enemy, current UnitAI behavior is :

    (1) Handle attack order

    (2) CheckInRange. if enemy not in range, goto (3)

    (3) MoveToTargetRange (min/max range)

    (4) When move is completed, goto (2)

    -------------------

    My question is:

    The MoveToTargetRange (especially max range!) is really useful to the ranged unit's approaching behavior?

    I found some faults:

    Situation 1:

    There are two units (A and B, A is ranged unit whose max range is 20).

    Let A attack B and B attack A.

    You will find that A often approach B but overstep and then walk back.

    It's only a bug and it could be fixed by adding some CheckInRange code in approaching timer.


    Situation 2:

    There are two units (A and B, A is ranged unit whose max range is 58).

    A is on one the side of river, B is on the other side.

    Now let A attack B and B flee A along the river bank.

    You will find A will lost B. (A won't go across bridge...)

    Is this behavior normally?

    After some thought, I've come to some conclusion: (maybe wrong)

    (1) The max range in approaching is only useful to the unit which has a very long range (eg: catapult) or target is a building.

    (2) Archer should be look as melee and not use weapon range as motion's maxrange to approach.
    It should use maxrange=0 approach and check its weapon range(maxrange) repeatly to decide attack.

  2. I have reproduced the issue which Ykkrosh mentioned.

    When the point precisely on the edge, we will get a very bad path.

    I modify some code in previous patch.

    It seems fixed now.

    //------------Modified Begin//If this is an axis-aligned shape, discard non-silhouette points easily.if (vertexes[n].quadInward == QUADRANT_BL)    if ((vertexes[curr.id].p.X > npos.X && vertexes[curr.id].p.Y > npos.Y) || (vertexes[curr.id].p.X < npos.X && vertexes[curr.id].p.Y < npos.Y))        continue; if (vertexes[n].quadInward == QUADRANT_TR)    if ((vertexes[curr.id].p.X < npos.X && vertexes[curr.id].p.Y < npos.Y) || (vertexes[curr.id].p.X > npos.X && vertexes[curr.id].p.Y > npos.Y))        continue; if (vertexes[n].quadInward == QUADRANT_TL)    if ((vertexes[curr.id].p.X > npos.X && vertexes[curr.id].p.Y < npos.Y) || (vertexes[curr.id].p.X < npos.X && vertexes[curr.id].p.Y > npos.Y))        continue; if (vertexes[n].quadInward == QUADRANT_BR)    if ((vertexes[curr.id].p.X < npos.X && vertexes[curr.id].p.Y > npos.Y) || (vertexes[curr.id].p.X > npos.X && vertexes[curr.id].p.Y < npos.Y))        continue;//------------Modified End
    • Like 1
  3. a unit starts from slightly inside a shape or precisely on the edge, and the silhouette-point-detection thing will mean it doesn't see any of the points on that shape at all.

    "silhouette-point-detection thing will mean it doesn't see any of the points"

    why? Fixed point precision problem? (I have not stress test it yet.)

    I think if it is a rare problem, can we do some dirty trick (eg: add some delta, if it is a precision problem?) and ensure most of time its behavior correct?

  4. After read short-range path source code deeply.

    I found a small problem which maybe cause performance degradation.

    The root cause is current algorithm can't discard non-silhouette points.

    I also read some books.

    In GPG2 "Optimizing Points-of-Visibility Pathfinding", it mentioned two optimizations:

    "Optimization #1": Only Consider Paths to Silhouette Points

    "Optimization #2": Only Consider Paths that Go Around the Corner

    So "Optimization #1" may be what we are missing.

    Implement "Optimization #1" is very easy, because there are axis-aligned box.

    I have written some code in CCmpPathfinder_Vertex.cpp

    // Check that the new vertex is in the right quadrant for the old vertexif (!(vertexes[curr.id].quadOutward & quad)){    // Hack: Always head towards the goal if possible, to avoid missing it if it's    // inside another unit    if (n != GOAL_VERTEX_ID)    {        continue;    }}//------------Modified Begin//If this is an axis-aligned shape, discard non-silhouette points easily.if (vertexes[n].quadInward == QUADRANT_BL)    if ((vertexes[curr.id].p.X >= npos.X && vertexes[curr.id].p.Y >= npos.Y) || (vertexes[curr.id].p.X <= npos.X && vertexes[curr.id].p.Y <= npos.Y))        continue;if (vertexes[n].quadInward == QUADRANT_TR)    if ((vertexes[curr.id].p.X <= npos.X && vertexes[curr.id].p.Y <= npos.Y) || (vertexes[curr.id].p.X >= npos.X && vertexes[curr.id].p.Y >= npos.Y))        continue;if (vertexes[n].quadInward == QUADRANT_TL)    if ((vertexes[curr.id].p.X >= npos.X && vertexes[curr.id].p.Y <= npos.Y) || (vertexes[curr.id].p.X <= npos.X && vertexes[curr.id].p.Y >= npos.Y))        continue;if (vertexes[n].quadInward == QUADRANT_BR)    if ((vertexes[curr.id].p.X <= npos.X && vertexes[curr.id].p.Y >= npos.Y) || (vertexes[curr.id].p.X >= npos.X && vertexes[curr.id].p.Y <= npos.Y))        continue;//------------Modified Endbool visible =    CheckVisibilityLeft(vertexes[curr.id].p, npos, edgesLeft) &&    CheckVisibilityRight(vertexes[curr.id].p, npos, edgesRight) &&    CheckVisibilityBottom(vertexes[curr.id].p, npos, edgesBottom) &&    CheckVisibilityTop(vertexes[curr.id].p, npos, edgesTop) &&    CheckVisibility(vertexes[curr.id].p, npos, edges);

    it seems faster than before.

    Has anyone here could review this code?

    Sorry for my broken english...

    • Like 1
  5. but it needed integrating with the short-range pathfinder (which needed redesigning itself)

    Thank Ykkrosh.

    Following #1756, I found that the short path is also a new enhancement. (#1942)

    It's a very great idea for short path performance improvement which make O(N^3) -> O(N^2) ! (http://www.wildfiregames.com/forum/index.php?showtopic=13042&&page=3#entry216735)

    Has this feature been integrated into the current short-range pathfinder?

    I am very sorry I have not deeply read current short path source code.

  6. After researched 0 A.D's source code (excellent work!),

    I have some confusion about long-range pathfinder's current implementation.

    In my understanding, each terrain tile should be split into 4x4 small cells for AStar. (This will make long path more accurately)

    And when a unit start a longpath, all static obstruction's tiles (small cells) will be expanded by this unit's clearnce.

    Has this feature be implemented now?

    I cant find any code about "obstruction's tile expanded by unit's clearnce in long path".

    I read the code:

    CCmpPathfinder_Tile.cpp

    void CCmpPathfinder::ComputePath(entity_pos_t x0, entity_pos_t z0, const Goal& goal, pass_class_t passClass, cost_class_t costClass, Path& path)

    The params seem not to relate unit's raduis or clearnce.....and where to expand tiles?

    Very thanks.

×
×
  • Create New...