1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

How to forbid diagonal move?

Discussion in 'Civ4 - SDK/Python' started by Inyah, Feb 25, 2012.

  1. Inyah

    Inyah Chieftain

    Joined:
    Jan 28, 2012
    Messages:
    45
    hi experts,

    i am trying to make a mod where seeunits can move on rivers (rivermasks). It actually works, including river-side-cities producing seeunits. Now I am trying to make the units stick to the flow of the river and not being able to take shortcuts by going diagonal (so basically only allowing the units to go north, east, west and south and not northeast etc.). Can someone give me a hint on how to do this? This is what I got (in "unitcanmoveinto" at cvUnit.cpp):

    Spoiler :
    switch (getDomainType())
    {
    case DOMAIN_SEA:
    // River Mod start
    if (pPlot->isRiverMask() == true || pPlot->isFriendlyCity(*this, true))

    {
    return true;
    break;
    }

    else
    {
    //River Mod end
    if (!pPlot->isWater() && !canMoveAllTerrain())
    {
    if (!pPlot->isFriendlyCity(*this, true) ||!pPlot->isCoastalLand())
    {
    return false;
    }

    }
    }
    break;


    I was thinking about adding something like this:

    Spoiler :

    if (pPlot->isRiverMask() == true || pPlot->isFriendlyCity(*this, true))
    {
    if (plotDirection == DIRECTION_NORTH)
    {
    return true;
    }

    if (plotDirektion == DIRECTION_SOUTHEAST)
    {
    return false;
    } //etc.

    break;
    }



    but i dont know how to get that direction. And I am not sure, if that would actually work, if then the program would understand to take the longer path via south and then east. (forgive my poor english, hope you can still understand what I mean...)

    Any ideas for this? :)
     
  2. platyping

    platyping Sleeping Dragon

    Joined:
    Oct 22, 2010
    Messages:
    4,626
    Location:
    Emerald Dreams
    Since I don't do SDK, I can only give you in pesudo code form.

    Add another if statement to check:
    If newplot.getX() == oldplot.getX() or newplot.getY() == oldplot.getY():

    Since moving left/right or up/down means either the X or the Y has to be the same
     
  3. Inyah

    Inyah Chieftain

    Joined:
    Jan 28, 2012
    Messages:
    45
    thanx - it helped. I did manage to forbid diagonal moves, but now the game isnt able to find a path to a distant plot, so I have to move the ships plotbyplot. well - taking it step by step :)

    if anyone is interested in the solution - its quite simple:
    Spoiler :

    if ((pPlot->getX_INLINE() == plot()->getX_INLINE()) || (pPlot->getY_INLINE() == plot()->getY_INLINE()))
    {
    return true;
    }

    else
    {
    return false;
    }
     
  4. Asaf

    Asaf Sleep Deprived

    Joined:
    Mar 22, 2010
    Messages:
    1,326
    The path finding algorithm uses a few functions in CvGameCoreUtils.cpp:
    pathValid(), pathDestValid() and a few more.
    (You can see them being passed to the algorithm in CvMap::setup())

    Try debugging them and see where it fails.
     
  5. Inyah

    Inyah Chieftain

    Joined:
    Jan 28, 2012
    Messages:
    45
    thanks for those functions. I tried a bit, but those are real tough ones. I cannot seem to find any way to tell the game to check if moving east and then north to get to northeast is a valid option. Somehow it doesnt seem to even consider that option but just breaks the path (or sometimes worse: just keeps moving between two tiles back and forth). If anyone has any ideas - I would be grateful.
     
  6. Asaf

    Asaf Sleep Deprived

    Joined:
    Mar 22, 2010
    Messages:
    1,326
    Well, I see a basic problem with your implementation (I don't know if it has anything to do with the path finding specific problem):
    canMoveInto() is built such that it has 'filters' along the way - you keep testing for all kinds of conditions, and if any fails the function returns false.
    The only place where this function returns true is at the end, after all tests were made. This is done so you don't skip any condition when testing if a unit can move into a plot.

    In your code you return true under a certain condition, and that way you might skip a few important conditions. I suggest you change it such that your condition only prevents the code from returning false on the 'iswater' condition, if needed.

    It might even solve your problem.
     
  7. Inyah

    Inyah Chieftain

    Joined:
    Jan 28, 2012
    Messages:
    45
    hmm I tried that, it didnt help with the path-problem. I must be a problem with the diagonal move forbidding. There seems to be a problem with the AI aswell, since it gets a bug when calling "candefend()" which also links to "canmoveinto()".

    This is the code I used now:

    Spoiler :

    switch (getDomainType())
    {
    case DOMAIN_SEA:
    // River Mod start
    if (pPlot->isRiverMask() == true || pPlot->isFriendlyCity(*this, true))
    {
    if (plot()->isRiverMask() == true || plot()->isFriendlyCity(*this, true))
    {
    if (pPlot->getX_INLINE() == (plot()->getX_INLINE()-1) && pPlot->getY_INLINE() == ((plot()->getY_INLINE()) -1))

    {
    return false;
    }

    if (pPlot->getX_INLINE() == (plot()->getX_INLINE()-1) && pPlot->getY_INLINE() == ((plot()->getY_INLINE()) +1))

    {
    return false;
    }

    if (pPlot->getY_INLINE() == (plot()->getY_INLINE()+1) && pPlot->getX_INLINE() == ((plot()->getX_INLINE()) +1))

    {
    return false;
    }

    if (pPlot->getY_INLINE() == (plot()->getY_INLINE()-1) && pPlot->getX_INLINE() == ((plot()->getX_INLINE()) +1))

    {
    return false;
    }

    }

    }

    else
    {
    //River Mod end
    if (!pPlot->isWater() && !canMoveAllTerrain())
    {
    if (!pPlot->isFriendlyCity(*this, true) || !pPlot->isCoastalLand())
    {
    return false;
    }

    }
    }



    I tried several versions of this. with this code the path sometimes workes for a bit, but at some point it always starts to loop. Maybe I missunderstood something in the code? Or else I'll just have to allow diagonal moving again...
     
  8. Inyah

    Inyah Chieftain

    Joined:
    Jan 28, 2012
    Messages:
    45

    ok I managed to get this thing done (took some sleepless nights ;)). The solution is to put the code into "pathvalid" (and not "canmoveinto"). Just in case anyone is interested in trying this themselves.

    this is the code:

    Spoiler :

    if (pSelectionGroup->getDomainType() == DOMAIN_SEA)
    {//RiverMod start
    if ((pFromPlot->isRiverMask() && pToPlot->isRiverMask()) || ((pFromPlot->isCoastalLand()&& pFromPlot->isRiverMask()) && pToPlot->isWater()) || ((pToPlot->isCoastalLand() && pToPlot->isRiverMask()) && pFromPlot->isWater()))
    {
    if ((node->m_iX == (parent->m_iX)-1) && (node->m_iY == ((parent->m_iY) -1)))
    {
    return FALSE;
    }


    if ((node->m_iX == (parent->m_iX)-1) && (node->m_iY == ((parent->m_iY) +1)))
    {
    return FALSE;
    }

    if ((node->m_iY == (parent->m_iY) +1) && (node->m_iX == ((parent->m_iX) +1)))
    {
    return FALSE;
    }


    if ((node->m_iY == (parent->m_iY) -1)&& (node->m_iX == ((parent->m_iX) +1)))
    {
    return FALSE;
    }

    }//RiverMod End

     
  9. Tholal

    Tholal Emperor

    Joined:
    May 19, 2009
    Messages:
    1,676
    That actually makes a lot of sense when you think about it. Glad you got it working!
     
  10. Sunjah

    Sunjah Chieftain

    Joined:
    Jul 4, 2007
    Messages:
    32
    Can you please share this mod. I do not have any experience with CIV IV python, so I have no clue where to put the code you left. The completed mod is what I want, though, can you share it please?
     
  11. CaptainMidnight

    CaptainMidnight Warlord

    Joined:
    Apr 16, 2006
    Messages:
    141
    I second that, I'd love to have a look at the sources and see it in action. I always wanted some river boats. It may be better to make only certain boats able to use rivers, gun boats and so forth.
     
  12. CaptainMidnight

    CaptainMidnight Warlord

    Joined:
    Apr 16, 2006
    Messages:
    141
    Or as an alternative rivers could work a little like Civ 2 where they doubled the unit speed. That might be another thing altogether.
     
  13. Inyah

    Inyah Chieftain

    Joined:
    Jan 28, 2012
    Messages:
    45

Share This Page