AI re-devlopment thread

Talk among developers, and propose and discuss general development planning/tackling/etc... feature in this forum.
safemode
Developer
Developer
Posts: 2150
Joined: Mon Apr 23, 2007 1:17 am
Location: Pennsylvania
Contact:

Re: AI re-devlopment thread

Post by safemode »

When i look at code, i want to look at as little whitespace as possible while still retaining the structure of the code.
This rides in the face of certain stylistic concerns of some people, and who's to say it's more important than those concerns, or less. ie, I hate one line opening brackets. But i hate lack of indentation more (or too much).

I propose this, and then we'll split this stuff into a new thread if need be:

No reformatting file commits. I can see this immediately becoming a race to enforce what one person considers correct over what others consider correct and we dont need that kind of crap right now.

You can format your code how you like, but it damn well better be in direct consequence to having to change that code.

And when i'm talking about format only changes, i'm talking about indentation and bracket placement. I'm not talking about stuff relating to how long functions are or how many classes per header and such. We can move ahead with that stuff, nobody is disagreeing there.
Ed Sweetman endorses this message.
safemode
Developer
Developer
Posts: 2150
Joined: Mon Apr 23, 2007 1:17 am
Location: Pennsylvania
Contact:

Re: AI re-devlopment thread

Post by safemode »

Getting back on AI for a second:

A lot of the non-aggressive class code is static. So it's in this file for a reason, that reason being that these functions have been made "shared" across every instance of the Aggressive class that uses them. It's going to take abit more time to re-organize this file than i originally thought.

anyways, Here is aggressive.cpp run through indent (simple neat too for fixing up files). This was achieved via just -linux, to match the code requirements of the linux kernel. Note, this has not been touched up yet to fix unnecessary line breaks, nor am i intending on committing this. Just a sample.

http://signal-lost.homeip.net/files/agg ... inuxindent

I'll continue working on figuring out just how we can re-organize aggressiveAI tomorrow. One thing i want to look into is if we can do a name change without mucking up python code, and without needing a stupid typedef to not muck it up. A better name for aggressiveAI is AciveAI, as it appears that the AI code in aggressive AI was meant to counter a more passive AI that simply reacts to things rather than act first. Aggressive is one way to see such behavior, but that denotes an emotional state, which is counter to what this code actually covers. So unless someone has a better name, I'll go with activeAI.

I can remove the static variable usage dealing with options without a problem, but the other static usages may be necessary, and in such a case, we wont be able to sanitize the source to the level we would like. static is Fun (tm).
Ed Sweetman endorses this message.
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: AI re-devlopment thread

Post by chuck_starchaser »

safemode wrote:Here is aggressive.cpp run through indent (simple neat too for fixing up files). This was achieved via just -linux, to match the code requirements of the linux kernel. Note, this has not been touched up yet to fix unnecessary line breaks, nor am i intending on committing this. Just a sample.

http://signal-lost.homeip.net/files/agg ... inuxindent
One thing I find remarkable is that as much as I hate indentation by 8 spaces, it allows me to follow the logic even with { in the same line, --though I still much prefer indentation by 4 and { in new line.
I'll continue working on figuring out just how we can re-organize aggressiveAI tomorrow. One thing i want to look into is if we can do a name change without mucking up python code, and without needing a stupid typedef to not muck it up. A better name for aggressiveAI is AciveAI, as it appears that the AI code in aggressive AI was meant to counter a more passive AI that simply reacts to things rather than act first. Aggressive is one way to see such behavior, but that denotes an emotional state, which is counter to what this code actually covers. So unless someone has a better name, I'll go with activeAI.
Sounds good to me.
I can remove the static variable usage dealing with options without a problem, but the other static usages may be necessary, and in such a case, we wont be able to sanitize the source to the level we would like. static is Fun (tm).
Necessary static variables could ve converted to class variables, which then shifts the problem of re-entrancy to a more standard problem of asynchronous object access.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Re: AI re-devlopment thread

Post by klauss »

chuck_starchaser wrote:That's false. There was an article years ago, not sure if in C++ Journal or DrDobbs (used to buy both), and the article was precisely about this problem, and he acknowledged that to many programmers formatting is more than just "a preference" and presented a solution that tied a formatter to (then CVS) to reformat code on checkout and commit. They were using the system at his company. I have a feeling you just don't WANT me to get this wish. This is damn important to me, if I'm going to get involved with the C++ code. But if you don't care for my help, then so be it. This is how so many great plans go to shit.
No, very simple: my experience with those tools is that they make mistakes.
So if you tie the tool to SVN, then you'll have to battle with those problems.
If you use the tool in your working directory, you'll have to battle with those problems just as well (only perhaps more controllably).

So ya, I don't want to use those tools. It's not necessary for me. If it is for you, feel free to use them personally. Just don't impose them on everybody else because they will be trouble at some point.
chuck_starchaser wrote:Now I capitalized what I've repeated so often, and you make a face about it. Safemode was saying he's tempted to run a formatter on all the code.
It's different. He'll use the formatter in a piece of code that is heavily broken, format-wise, and only once. You're proposing to turn it into an SVN hook - can you not see the difference?
chuck_starchaser wrote:so I can format the code in a way I can work with it, and then format it back before committing.
What is so evil about my request?
You don't have to request it, you can simply do it in your working directory. I don't see why it has to be an SVN hook.
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: AI re-devlopment thread

Post by chuck_starchaser »

klauss wrote:
chuck_starchaser wrote:That's false. There was an article years ago, not sure if in C++ Journal or DrDobbs (used to buy both), and the article was precisely about this problem, and he acknowledged that to many programmers formatting is more than just "a preference" and presented a solution that tied a formatter to (then CVS) to reformat code on checkout and commit. They were using the system at his company. I have a feeling you just don't WANT me to get this wish. This is damn important to me, if I'm going to get involved with the C++ code. But if you don't care for my help, then so be it. This is how so many great plans go to shit.
No, very simple: my experience with those tools is that they make mistakes.
So if you tie the tool to SVN, then you'll have to battle with those problems.
I see. So, tying them to svn is not a good idea; I can live with that.
If you use the tool in your working directory, you'll have to battle with those problems just as well (only perhaps more controllably).
That's fine with me.
So ya, I don't want to use those tools. It's not necessary for me. If it is for you, feel free to use them personally. Just don't impose them on everybody else because they will be trouble at some point.
I wasn't really insisting on tying them to svn; all I asked for was a tool and a config string, so I can reformat code to the taste of the majority here before I commit. Anyways, I'm playing with uncrustify right now, and I'm hoping to be able to come up with both configs myself; --I'm calling them unc_me.cfg and unc_them.cfg.
chuck_starchaser wrote:Now I capitalized what I've repeated so often, and you make a face about it. Safemode was saying he's tempted to run a formatter on all the code.
It's different. He'll use the formatter in a piece of code that is heavily broken, format-wise, and only once. You're proposing to turn it into an SVN hook - can you not see the difference?
But I wasn't; that was one option; the other option was simply a tool and a configuration. Safemode runs the initial formatter, and if I know what the configuration for it is, I can reformat to suit my needs, work with the file, then format back with his settings, and it shouldn't be much different than editing the file directly.
chuck_starchaser wrote:so I can format the code in a way I can work with it, and then format it back before committing.
What is so evil about my request?
You don't have to request it, you can simply do it in your working directory. I don't see why it has to be an SVN hook.
It doesn't.
safemode
Developer
Developer
Posts: 2150
Joined: Mon Apr 23, 2007 1:17 am
Location: Pennsylvania
Contact:

Re: AI re-devlopment thread

Post by safemode »

Keep in mind too, when i say i am running a formatter on something, I have to go through line by line and fix various lines (c++ formatting is riddled with mistakes with such tools). It's not something that can just be batch processed and let go. So i only tend to use it on stuff i'm going to be messing with anyway. And I haven't done it in VS (not in a long long time anyway) at all yet, and wasn't intending to unilaterally

The discrepancies with style is why i suggested we only deal with indentation. This would still need to be doublechecked after running on a file, but it would be much less intrusive on everyone's personal coding habits. In many decent editors, the tab is customizable (either as a real tab or converting to spaces and the size/amount thereof). But even in those that aren't, we are less likely to run up against a problem where the need to run it through a formatting program lacks a certain feature if all we care about is indentation.

Ie. windows developers may not have the same formatter available in linux land, so what are they to do? Have one of the linux developers process their patches ? Or even in linux land, which formatter would we decide on? There are many. I would just rather avoid all this mess with formatting and only fix the indentations, since many many files become nearly unreadable when nothing is indented correctly.

About AggressiveAI:
I dont think we're ready to split this file into anything yet. I dont know if we ever will. The long switch statements would only be shortened by making them call separate functions consisting of each case, which adds a function call and slows things down, and switch statements are more efficient than a long ifelse tree. So while it looks ugly, i dont think it you're gonna be able to optimize this out. Further, outside of tiny micro-optimizations, i dont think anything in here is really horribly inefficient considering what it does. My previous profiles which i did for collisions did not show barely any cpu being used up by the AI at all, (granted i wasn't dogfighting anyone). So other than some simple variable -> options changes and some code re-formatting, I'm not seeing much we can do here. Not without full on writing a new AI system and this isn't the time nor do we have any such code ready to do such a thing.
Ed Sweetman endorses this message.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Re: AI re-devlopment thread

Post by klauss »

safemode wrote:I dont think we're ready to split this file into anything yet. I dont know if we ever will. The long switch statements would only be shortened by making them call separate functions consisting of each case, which adds a function call and slows things down, and switch statements are more efficient than a long ifelse tree. So while it looks ugly, i dont think it you're gonna be able to optimize this out.
As I said, optimizing this means refactoring it.
Switch statements are converted into a lookup table and indirect jumps by the compiler, which is fast but unpredictable. So when you get to such a statement, the whole pipeline gets flushed - it's a big performance hit. But only if the switch is hot.

Now... not all AI is hot, you're probably not seeing it on the profilings because it must have been tuned to run less and less often. I'll have to do some profiling of my own. In any case a more efficient architecture would enable us to implement smarter AIs, and that's something everybody wants IIRC.
safemode wrote:Further, outside of tiny micro-optimizations, i dont think anything in here is really horribly inefficient considering what it does.
Look again. There's some unneeded string parsing there at rather critical paths (critical if the AI gets evaluated often).
safemode wrote:My previous profiles which i did for collisions did not show barely any cpu being used up by the AI at all, (granted i wasn't dogfighting anyone). So other than some simple variable -> options changes and some code re-formatting, I'm not seeing much we can do here. Not without full on writing a new AI system and this isn't the time nor do we have any such code ready to do such a thing.
Ya, the formatting is a no brainer, and small cleanup can be done too.
And documentation.
Try to document stuff as you go (as you figure out how the stuff works).
If anyone can figure out this AI system, it will be a big gain.

@chuck: great, so I misunderstood. Sorry ;)
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
pheonixstorm
Elite
Elite
Posts: 1567
Joined: Tue Jan 26, 2010 2:03 am

Re: AI re-devlopment thread

Post by pheonixstorm »

chuck_starchaser wrote:
klauss wrote:
chuck_starchaser wrote:That's false. There was an article years ago, not sure if in C++ Journal or DrDobbs (used to buy both), and the article was precisely about this problem, and he acknowledged that to many programmers formatting is more than just "a preference" and presented a solution that tied a formatter to (then CVS) to reformat code on checkout and commit. They were using the system at his company. I have a feeling you just don't WANT me to get this wish. This is damn important to me, if I'm going to get involved with the C++ code. But if you don't care for my help, then so be it. This is how so many great plans go to shit.
No, very simple: my experience with those tools is that they make mistakes.
So if you tie the tool to SVN, then you'll have to battle with those problems.
I see. So, tying them to svn is not a good idea; I can live with that.
I actually think this was done client side. In one of the links I provided, a formatter hook was added to TortioseSVN to run during commit. I'm pretty sure it could be made to work at checkout as well. If it was done server side.. well that could cause some nasty problems if the formatter sucked.
safemode wrote:Ie. windows developers may not have the same formatter available in linux land, so what are they to do? Have one of the linux developers process their patches ? Or even in linux land, which formatter would we decide on? There are many. I would just rather avoid all this mess with formatting and only fix the indentations, since many many files become nearly unreadable when nothing is indented correctly.
The ones i linked too I believe are cross-platform, will have to double check. Astyle was regarded as the best by most of the people who needed one.
safemode wrote:About AggressiveAI:
I dont think we're ready to split this file into anything yet. I dont know if we ever will. The long switch statements would only be shortened by making them call separate functions consisting of each case, which adds a function call and slows things down, and switch statements are more efficient than a long ifelse tree. So while it looks ugly, i dont think it you're gonna be able to optimize this out. Further, outside of tiny micro-optimizations, i dont think anything in here is really horribly inefficient considering what it does. My previous profiles which i did for collisions did not show barely any cpu being used up by the AI at all, (granted i wasn't dogfighting anyone). So other than some simple variable -> options changes and some code re-formatting, I'm not seeing much we can do here. Not without full on writing a new AI system and this isn't the time nor do we have any such code ready to do such a thing.
Refering to just aggressiveai.cpp or all the AI files?
Because of YOU Arbiter, MY kids? can't get enough gas. OR NIPPLE! How does that mkae you feeeel? ~ Halo
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: AI re-devlopment thread

Post by chuck_starchaser »

@Safemode: If you can break it into functions, function call overhead could be prevented by #inline-ing the functions.
And what we gain really, is just the function names, and an easier to read main function, but it'd be a start anyways.

I'm about half way through setting the parameters for uncrustify; both for myself and for VS. Sorry it's taking so long; it's 370+ parameters to go through; and I'm having trouble with public: private: and protected: (wanted them to have relative indentation, so as to be able to have nested class declarations, but it's giving me trouble).
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: AI re-devlopment thread

Post by chuck_starchaser »

Done with the uncrustify configs.
Try this, Safemode:

Code: Select all

#include "config.h"
#include "aggressive.h"
#include "event_xml.h"
#include "script.h"
#include <list>
#include <vector>
#include "vs_globals.h"
#include "config_xml.h"
#include "xml_support.h"
#include "cmd/unit_generic.h"
#include "communication.h"
#include "cmd/script/flightgroup.h"
#include "flybywire.h"
#include "hard_coded_scripts.h"
#include "cmd/script/mission.h"
#include "gfx/cockpit_generic.h"
#include "lin_time.h"
#include "faction_generic.h"
#include "cmd/role_bitmask.h"
#include "cmd/unit_util.h"
#include "warpto.h"
#include "cmd/csv.h"
#include "universe_util.h"
#include "vs_random.h"
#include "python/python_compile.h"
#include "cmd/unit_find.h"
#include "faction_generic.h"
#include "docking.h"
using namespace Orders;
const EnumMap::Pair                     element_names[] = {
    EnumMap::Pair("AggressiveAI",                AggressiveAI::AGGAI),
    EnumMap::Pair("UNKNOWN",                     AggressiveAI::UNKNOWN),
    EnumMap::Pair("Distance",                    AggressiveAI::DISTANCE),
    EnumMap::Pair("MeterDistance",               AggressiveAI::METERDISTANCE),
    EnumMap::Pair("Threat",                      AggressiveAI::THREAT),
    EnumMap::Pair("FShield",                     AggressiveAI::FSHIELD),
    EnumMap::Pair("LShield",                     AggressiveAI::LSHIELD),
    EnumMap::Pair("RShield",                     AggressiveAI::RSHIELD),
    EnumMap::Pair("BShield",                     AggressiveAI::BSHIELD),
    EnumMap::Pair("Hull",                        AggressiveAI::HULL),
    EnumMap::Pair("Facing",                      AggressiveAI::FACING),
    EnumMap::Pair("Movement",                    AggressiveAI::MOVEMENT),
    EnumMap::Pair("FShield_Heal_Rate",           AggressiveAI::FSHIELD_HEAL_RATE),
    EnumMap::Pair("BShield_Heal_Rate",           AggressiveAI::BSHIELD_HEAL_RATE),
    EnumMap::Pair("LShield_Heal_Rate",           AggressiveAI::LSHIELD_HEAL_RATE),
    EnumMap::Pair("RShield_Heal_Rate",           AggressiveAI::RSHIELD_HEAL_RATE),
    EnumMap::Pair("FArmor_Heal_Rate",            AggressiveAI::FARMOR_HEAL_RATE),
    EnumMap::Pair("BArmor_Heal_Rate",            AggressiveAI::BARMOR_HEAL_RATE),
    EnumMap::Pair("LArmor_Heal_Rate",            AggressiveAI::LARMOR_HEAL_RATE),
    EnumMap::Pair("RArmor_Heal_Rate",            AggressiveAI::RARMOR_HEAL_RATE),
    EnumMap::Pair("Hull_Heal_Rate",              AggressiveAI::HULL_HEAL_RATE),
    EnumMap::Pair("Target_Faces_You",            AggressiveAI::TARGET_FACES_YOU),
    EnumMap::Pair("Target_In_Front_Of_You",      AggressiveAI::TARGET_IN_FRONT_OF_YOU),
    EnumMap::Pair("Rand",                        AggressiveAI::RANDOMIZ),
    EnumMap::Pair("Target_Going_Your_Direction", AggressiveAI::TARGET_GOING_YOUR_DIRECTION)
};
const EnumMap                           AggressiveAIel_map(element_names, 25);
using std::pair;

vsUMap< string, AIEvents::ElemAttrMap* >logic;

extern bool CheckAccessory (Unit *tur);
//extern void TurretFAW(Unit *parent); /*
static void TurretFAW (Unit *parent)
{
    un_iter iter = parent->getSubUnits();
    Unit   *un;
    while ( NULL != (un = *iter) ) {
        if ( !CheckAccessory(un) ) {
            un->EnqueueAIFirst( new Orders::FireAt(15.0f) );
            un->EnqueueAIFirst( new Orders::FaceTarget(false, 3) );
        }
        TurretFAW(un);
        ++iter;
    }
}

static vsUMap< string, string >getAITypes ()
{
    vsUMap< string, string >ret;
    VSFileSystem::VSFile    f;
    VSError                 err = f.OpenReadOnly("VegaPersonalities.csv", AiFile);
    if (err <= Ok) {
        CSVTable                             table( f, f.GetRoot() );
        vsUMap< std::string, int >::iterator browser = table.rows.begin();
        for (; browser != table.rows.end(); ++browser) {
            string rowname = (*browser).first;
            CSVRow row(&table, rowname);
            for (unsigned int i = 1; i < table.key.size(); ++i) {
                string hasher = rowname;
                if (i != 1) hasher = rowname+"%"+table.key[i];
                string rawrow = row[i];
                if (rawrow.length() > 0) {
                    ret[hasher] = rawrow;
                }
            }
        }
        f.Close();
    }
    return ret;
}

static string select_from_space_list (string inp, unsigned int seed)
{
    if (inp.length() == 0) return "";
    int               count  = 1;
    string::size_type len    = inp.length();
    for (unsigned int i = 0; i < len; ++i) {
        if (inp[i] == ' ')
            count++;
    }
    count = seed%count;
    int               ncount = 0;
    unsigned int      j;
    for (j = 0; j < len; ++j) {
        if (inp[j] == ' ') ncount++;
        if (ncount >= count) break;
    }
    if (inp[j] == ' ') j++;
    inp = inp.substr(j);
    if ( ( len = inp.find(" ") ) != string::npos )
        inp = inp.substr(0, len);
    return inp;
}

static AIEvents::ElemAttrMap * getLogicOrInterrupt (string name,
                                                    int faction,
                                                    string unittype,
                                                    vsUMap< string, AIEvents::ElemAttrMap* > &mymap,
                                                    int personalityseed)
{
    string                                             append      = "agg";
    static vsUMap< string, string >                    myappend    = getAITypes();
    vsUMap< string, string >::iterator                 iter;
    string                                             factionname = FactionUtil::GetFaction(faction);
    if ( ( iter = myappend.find(factionname+"%"+unittype) ) != myappend.end() )
        append = select_from_space_list( (*iter).second, personalityseed );

    else if ( ( iter = myappend.find(factionname) ) != myappend.end() )
        append = select_from_space_list( (*iter).second, personalityseed );
    if (append.length() == 0) append = "agg";
    string                                             hashname    = name+"."+append;
    vsUMap< string, AIEvents::ElemAttrMap* >::iterator i           = mymap.find(hashname);
    if ( i == mymap.end() ) {
        AIEvents::ElemAttrMap *attr = new AIEvents::ElemAttrMap(AggressiveAIel_map);
        string                 filename(name+"."+append+".xml");
        AIEvents::LoadAI( filename.c_str(), *attr, FactionUtil::GetFaction(faction) );
        mymap.insert( pair< string, AIEvents::ElemAttrMap* > (hashname, attr) );
        return attr;
    }
    return i->second;
}

static AIEvents::ElemAttrMap * getProperLogicOrInterruptScript (string name,
                                                                int faction,
                                                                string unittype,
                                                                bool interrupt,
                                                                int personalityseed)
{
    return getLogicOrInterrupt(name, faction, unittype, logic, personalityseed);
}

static AIEvents::ElemAttrMap * getProperScript (Unit *me, Unit *targ, bool interrupt, int personalityseed)
{
    if (!me || !targ) {
        string nam = "eject";
        int    fac = 0;
        if (me) {
            fac = me->faction;
            nam = me->name;
        }
        return getProperLogicOrInterruptScript("default", fac, nam, interrupt, personalityseed);
    }
    return getProperLogicOrInterruptScript(ROLES::getRoleEvents( me->attackPreference(),
                                                                targ->unitRole() ), me->faction, me->name, interrupt,
                                           personalityseed);
}

inline std::string GetRelationshipColor (float rel)
{
    if (rel >= 1) return "#00FF00";
    if (rel <= -1) return "#FF0000";
    rel += 1.;
    rel /= 2.;
    char str[20]; //Just in case all 8 digits of both #s end up inside the string for some reason.
    sprintf( str, "#%2X%2X00", (int) ( (1-rel)*256 ), (int) (rel*256) );
    return str;
}

unsigned int DoSpeech (Unit *un, Unit *player_un, const FSM::Node &node)
{
    unsigned int dummy  = 0;
    string       speech = node.GetMessage(dummy);
    string       myname("[Static]");
    if (un != NULL) {
        myname = un->isUnit() == PLANETPTR ? un->name : un->getFullname();
        Flightgroup *fg = un->getFlightgroup();
        if (fg && fg->name != "base" && fg->name != "Base")
            myname = fg->name+" "+XMLSupport::tostring( un->getFgSubnumber() )+", "+un->getFullname();

        else if (myname.length() == 0) myname = un->name;
        if (player_un != NULL) {
            if (player_un == un)
                myname = std::string("#0033FF")+myname+"#000000";

            else {
                float rel = un->getRelation(player_un);
                myname = GetRelationshipColor(rel)+myname+"#000000";
            }
        }
    }
    mission->msgcenter->add(myname, "all", GetRelationshipColor(node.messagedelta*10)+speech+"#000000"); //multiply by 2 so colors are easier to tell
    return dummy;
}

void LeadMe (Unit *un, string directive, string speech, bool changetarget)
{
    if (un != NULL) {
        for (unsigned int i = 0; i < _Universe->numPlayers(); i++) {
            Unit *pun = _Universe->AccessCockpit(i)->GetParent();
            if (pun) {
                if ( pun->getFlightgroup() == un->getFlightgroup() )
                    DoSpeech( un, pun, FSM::Node::MakeNode(speech, .1) );
            }
        }
        Flightgroup *fg = un->getFlightgroup();
        if (fg) {
            if (fg->leader.GetUnit() != un) {
                if ( ( !_Universe->isPlayerStarship( fg->leader.GetUnit() ) ) || _Universe->isPlayerStarship(un) )
                    fg->leader.SetUnit(un);
            }
            fg->directive = directive;
            if (changetarget) fg->target.SetUnit( un->Target() );
            if ( (directive == "") ) fg->target.SetUnit(NULL);
        }
    }
}

static float aggressivity = 2.01;
static int   randomtemp;
AggressiveAI::AggressiveAI (const char *filename, Unit *target) : FireAt()
    , logic( getProperScript( NULL, NULL, "default", randomtemp = rand() ) )
{
    currentpriority    = 0;
    last_jump_time     = 0;
    nav                = QVector(0, 0, 0);
    personalityseed    = randomtemp;
    last_jump_distance = FLT_MAX;
    interruptcurtime   = 0;
    creationtime       = getNewTime();
    jump_time_check    = 1;
    last_time_insys    = true;
    logiccurtime       = logic->maxtime; //set it to the time allotted
    obedient           = true;
    if (aggressivity == 2.01) {
        static float defagg = XMLSupport::parse_float( vs_config->getVariable("unit", "aggressivity", "2") );
        aggressivity = defagg;
    }
    if (target != NULL)
        AttachOrder(target);
    last_directive     = filename;
    //AIEvents::LoadAI (filename,logic,"neutral");
    //AIEvents::LoadAI (interruptname,interrupt,"neutral");
}

void AggressiveAI::SetParent (Unit *parent1)
{
    FireAt::SetParent(parent1);
    string::size_type which = last_directive.find("|");
    string            filename( string("default.agg.xml") );
    string            interruptname( string("default.int.xml") );
    if (which != string::npos) {
        filename      = last_directive.substr(0, which);
        interruptname = last_directive.substr(which+1);
    }
    last_directive    = "b"; //prevent escort race condition
    //INIT stored stuff
    Fshield_prev      = parent->graphicOptions.InWarp ? 1 : parent->FShieldData();
    Fshield_rate_old  = 0.0;
    Fshield_prev_time = UniverseUtil::GetGameTime();
    Bshield_prev      = parent->graphicOptions.InWarp ? 1 : parent->BShieldData();
    Bshield_rate_old  = 0.0;
    Bshield_prev_time = UniverseUtil::GetGameTime();
    Lshield_prev      = parent->graphicOptions.InWarp ? 1 : parent->LShieldData();
    Lshield_rate_old  = 0.0;
    Lshield_prev_time = UniverseUtil::GetGameTime();
    Rshield_prev      = parent->graphicOptions.InWarp ? 1 : parent->RShieldData();
    Rshield_rate_old  = 0.0;
    Rshield_prev_time = UniverseUtil::GetGameTime();
    Farmour_prev      = 1.0;
    Farmour_rate_old  = 0.0;
    Farmour_prev_time = UniverseUtil::GetGameTime();
    Barmour_prev      = 1.0;
    Barmour_rate_old  = 0.0;
    Barmour_prev_time = UniverseUtil::GetGameTime();
    Larmour_prev      = 1.0;
    Larmour_rate_old  = 0.0;
    Larmour_prev_time = UniverseUtil::GetGameTime();
    Rarmour_prev      = 1.0;
    Rarmour_rate_old  = 0.0;
    Rarmour_prev_time = UniverseUtil::GetGameTime();
    Hull_prev         = parent->GetHullPercent();
    Hull_rate_old     = 0.0;
    Hull_prev_time    = UniverseUtil::GetGameTime();
}

void AggressiveAI::SignalChosenTarget ()
{
    if (parent)
        logic = getProperScript(parent, parent->Target(), false, personalityseed);
    FireAt::SignalChosenTarget();
}

bool AggressiveAI::ExecuteLogicItem (const AIEvents::AIEvresult &item)
{
    if (item.script.length() != 0) {
        Order *tmp = new ExecuteFor(new AIScript( item.script.c_str() ), item.timetofinish);
        //parent->EnqueueAI (tmp);
        EnqueueOrder(tmp);
        return true;
    } else
        return false;
}

bool AggressiveAI::ProcessLogicItem (const AIEvents::AIEvresult &item)
{
    float        value      = 0.0;
    static float game_speed = XMLSupport::parse_float( vs_config->getVariable("physics", "game_speed", "1") );
    static float game_accel = XMLSupport::parse_float( vs_config->getVariable("physics", "game_accel", "1") );
    switch ( abs(item.type) )
    {
    case DISTANCE:
        value = distance;
        break;
    case METERDISTANCE:
        {
            Unit *targ = parent->Target();
            if (targ) {
                Vector PosDifference = targ->Position().Cast()-parent->Position().Cast();
                float  pdmag         = PosDifference.Magnitude();
                value = ( pdmag-parent->rSize()-targ->rSize() );
                float  myvel         = PosDifference.Dot( parent->GetVelocity()-targ->GetVelocity() )/value; ///pdmag;
                if (myvel > 0) value -= myvel*myvel/( 2*( parent->Limits().retro/parent->GetMass() ) );
            } else
                value = 10000;
            value /= game_speed; /*game_accel*/
        }
        break;
    case THREAT:
        value = parent->GetComputerData().threatlevel;
        break;
    case FSHIELD:
        value = parent->graphicOptions.InWarp ? 1 : parent->FShieldData();
        break;
    case BSHIELD:
        value = parent->graphicOptions.InWarp ? 1 : parent->BShieldData();
        break;
    case HULL:
        {
            value = parent->GetHullPercent();
            break;
        }
    case LSHIELD:
        value = parent->graphicOptions.InWarp ? 1 : parent->LShieldData();
        break;
    case RSHIELD:
        value = parent->graphicOptions.InWarp ? 1 : parent->RShieldData();
        break;
    case FSHIELD_HEAL_RATE:
        {
            double delta_t = UniverseUtil::GetGameTime()-Fshield_prev_time;
            if (delta_t > 0.5) {
                //0.5 = reaction time limit for hit rate
                double delta_v = parent->graphicOptions.InWarp ? 1 : parent->FShieldData()-Fshield_prev;
                value             = delta_v/delta_t;
                Fshield_rate_old  = value;
                Fshield_prev_time = UniverseUtil::GetGameTime();
                Fshield_prev      = parent->graphicOptions.InWarp ? 1 : parent->FShieldData();
            } else  value = Fshield_rate_old;  //if(value != 0.0)
//{
//string mystr ("Fshield "+XMLSupport::tostring (value));
//UniverseUtil::IOmessage (0,"game","all",mystr);
//}
            break;
        }
    case BSHIELD_HEAL_RATE:
        {
            double delta_t = UniverseUtil::GetGameTime()-Bshield_prev_time;
            if (delta_t > 0.5) {
                //0.5 = reaction time limit for hit rate
                double delta_v = parent->graphicOptions.InWarp ? 1 : parent->BShieldData()-Bshield_prev;
                value             = delta_v/delta_t;
                Bshield_rate_old  = value;
                Bshield_prev_time = UniverseUtil::GetGameTime();
                Bshield_prev      = parent->graphicOptions.InWarp ? 1 : parent->BShieldData();
            } else  value = Bshield_rate_old;  //if(value != 0.0)
//{
//string mystr ("Fshield "+XMLSupport::tostring (value));
//UniverseUtil::IOmessage (0,"game","all",mystr);
//}
            break;
        }
    case LSHIELD_HEAL_RATE:
        {
            double delta_t = UniverseUtil::GetGameTime()-Lshield_prev_time;
            if (delta_t > 0.5) {
                //0.5 = reaction time limit for hit rate
                double delta_v = parent->graphicOptions.InWarp ? 1 : parent->LShieldData()-Lshield_prev;
                value             = delta_v/delta_t;
                Lshield_rate_old  = value;
                Lshield_prev_time = UniverseUtil::GetGameTime();
                Lshield_prev      = parent->graphicOptions.InWarp ? 1 : parent->LShieldData();
            } else  value = Lshield_rate_old;  //if(value != 0.0)
//{
//string mystr ("Fshield "+XMLSupport::tostring (value));
//UniverseUtil::IOmessage (0,"game","all",mystr);
//}
            break;
        }
    case RSHIELD_HEAL_RATE:
        {
            double delta_t = UniverseUtil::GetGameTime()-Rshield_prev_time;
            if (delta_t > 0.5) {
                //0.5 = reaction time limit for hit rate
                double delta_v = parent->graphicOptions.InWarp ? 1 : parent->RShieldData()-Rshield_prev;
                value             = delta_v/delta_t;
                Rshield_rate_old  = value;
                Rshield_prev_time = UniverseUtil::GetGameTime();
                Rshield_prev      = parent->graphicOptions.InWarp ? 1 : parent->RShieldData();
            } else  value = Rshield_rate_old;  //if(value != 0.0)
//{
//string mystr ("Fshield "+XMLSupport::tostring (value));
//UniverseUtil::IOmessage (0,"game","all",mystr);
//}
            break;
        }
    case FARMOR_HEAL_RATE:
        value = 0.0;
        break;
    case BARMOR_HEAL_RATE:
        value = 0.0;
        break;
    case LARMOR_HEAL_RATE:
        value = 0.0;
        break;
    case RARMOR_HEAL_RATE:
        value = 0.5;
        break;
    case HULL_HEAL_RATE:
        {
            double delta_t = UniverseUtil::GetGameTime()-Hull_prev_time;
            if (delta_t > 0.5) {
                //0.5 = reaction time limit for hit rate
                double delta_v = parent->GetHullPercent()-Hull_prev;
                value          = delta_v/delta_t;
                Hull_rate_old  = value;
                Hull_prev_time = UniverseUtil::GetGameTime();
                Hull_prev      = parent->GetHullPercent();
            } else  value = Hull_rate_old;  //if(value != 0.0)
//{
//string mystr ("Fshield "+XMLSupport::tostring (value));
//UniverseUtil::IOmessage (0,"game","all",mystr);
//}
            break;
        }
    case TARGET_FACES_YOU:
        {
            value = 0.0;
            Unit *targ = parent->Target();
            if (targ) {
                Vector Q;
                Vector P;
                Vector R;

                Vector PosDelta = ( parent->Position() )-( targ->Position() );
                PosDelta = PosDelta/PosDelta.Magnitude();
                targ->GetOrientation(Q, P, R);
                value    = PosDelta.Dot(R);
            }
        }
        break;
    case TARGET_IN_FRONT_OF_YOU:
        {
            value = 0.0;
            Unit *targ = parent->Target();
            if (targ) {
                Vector Q;
                Vector P;
                Vector S;
                Vector PosDelta = ( targ->Position() )-( parent->Position() );
                PosDelta = PosDelta/PosDelta.Magnitude();
                parent->GetOrientation(Q, P, S);
                value    = PosDelta.Dot(S);
            }
        }
        break;
    case TARGET_GOING_YOUR_DIRECTION:
        {
            value = 0.0;
            Unit *targ = parent->Target();
            if (targ) {
                Vector Q;
                Vector P;
                Vector R;
                Vector S;
                parent->GetOrientation(Q, P, S);
                targ->GetOrientation(Q, P, R);
                value = S.Dot(R);
            }
        }
        break;
    case FACING:
        //return parent->getAIState()->queryType (Order::FACING)==NULL;
        return queryType(Order::FACING) == NULL;

    case MOVEMENT:
        //return parent->getAIState()->queryType (Order::MOVEMENT)==NULL;
        return queryType(Order::MOVEMENT) == NULL;

    case RANDOMIZ:
        value = ( (float) rand() )/RAND_MAX;
        break;
    default:
        return false;
    }
    return item.Eval(value);
}
Continued on next post, since this stupid thing limits message size to 60k chars...
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: AI re-devlopment thread

Post by chuck_starchaser »

... continuing ...

Code: Select all

bool AggressiveAI::ProcessLogic (AIEvents::ElemAttrMap &logi, bool inter)
{
    //go through the logic.
    bool                                                       retval = false;
    //Unit * tmp = parent->Target();
    //distance = tmp? (tmp->Position()-parent->Position()).Magnitude()-parent->rSize()-tmp->rSize() : FLT_MAX;
    std::vector< std::list< AIEvents::AIEvresult > >::iterator i      = logi.result.begin();
    for (; i != logi.result.end(); i++) {
        std::list< AIEvents::AIEvresult >::iterator j;
        bool                                        trueit = true;
        for (j = i->begin(); j != i->end(); j++) {
            if ( !ProcessLogicItem(*j) ) {
                trueit = false;
                break;
            }
        }
        if ( trueit && j == i->end() ) {
            //do it
            if ( j != i->begin() ) j--;
            if ( j != i->end() ) {
                float priority = (*j).priority;
                if (priority > this->currentpriority || !inter) {
                    if (inter) {
                        //parent->getAIState()->eraseType (Order::FACING);
                        //parent->getAIState()->eraseType (Order::MOVEMENT);
                        eraseType(Order::FACING);
                        eraseType(Order::MOVEMENT);
                    }
                    j                = i->begin();
                    logiccurtime     = 0;
                    interruptcurtime = 0;
                    if ( j != i->end() ) {
                        while ( j != i->end() ) {
                            if ( ExecuteLogicItem(*j) ) {
                                this->currentpriority = priority;
                                logiccurtime         += (*j).timetofinish;
                                interruptcurtime     += (*j).timetointerrupt;
                                //AIEvents::AIEvresult tmp = *j;
                                //i->erase(j);
                                retval                = true;
                                //i->push_back (tmp);
                            }
                            j++;
                        }
                        if (retval) break;
                    }
                }
            }
        }
    }
    return retval;
}

Unit * GetThreat (Unit *parent, Unit *leader)
{
    Unit *th        = NULL;
    Unit *un        = NULL;
    bool  targetted = false;
    float mindist   = FLT_MAX;
    for (un_iter ui = _Universe->activeStarSystem()->getUnitList().createIterator();
         (un = *ui);
         ++ui) {
        if (parent->getRelation(un) < 0) {
            float d             = ( un->Position()-leader->Position() ).Magnitude();
            bool  thistargetted = (un->Target() == leader);
            if ( !th || (thistargetted && !targetted) || ( ( thistargetted || (!targetted) ) && d < mindist ) ) {
                th        = un;
                targetted = thistargetted;
                mindist   = d;
            }
        }
    }
    return th;
}

extern Cargo * GetMasterPartList (const char*);

bool AggressiveAI::ProcessCurrentFgDirective (Flightgroup *fg)
{
    bool retval = false;
    if (fg != NULL) {
        Unit *leader = fg->leader.GetUnit();
        if ( last_directive.empty() )
            last_directive = fg->directive;
        if (fg->directive != last_directive) {
            static bool forceobedient = XMLSupport::parse_bool( vs_config->getVariable("AI", "always_obedient", "true") );
            if (forceobedient) obedient = true;
            else if ( float( rand() )/RAND_MAX < (obedient ? (1-logic->obedience) : logic->obedience) )
                obedient = !obedient;
            if (obedient) {
                eraseType(Order::FACING);
                eraseType(Order::MOVEMENT);
                Unit *targ = parent->Target();
                if (targ) {
                    bool attacking = fg->directive.length() > 0;
                    if (attacking) attacking = tolower(fg->directive[0]) == 'a';
                    if ( ( !isJumpablePlanet(targ) ) && attacking == false )
                        parent->Target(NULL);
                }
            } else {
                CommunicationMessage c(parent, leader, NULL, 0);
                c.SetCurrentState(c.fsm->GetNoNode(), NULL, 0);
                Order               *lo = leader->getAIState();
                if (lo) lo->Communicate(c);
            }
        }
        if (obedient) {
            void *parentowner;
            void *leaderowner = leader;
            parentowner = parent->owner ? parent->owner : parent;
            leaderowner = leader->owner ? leader->owner : leader;
            if (fg->directive.find("k") != string::npos || fg->directive.find("K") != string::npos) {
                Unit *targ   = fg->target.GetUnit();
                bool  callme = false;
                if ( targ && (targ->faction != parent->faction) ) {
                    if ( targ->InCorrectStarSystem( _Universe->activeStarSystem() ) ) {
                        CommunicationMessage c(parent, leader, NULL, 0);
                        c.SetCurrentState(c.fsm->GetNoNode(), NULL, 0);
                        if ( parent->InRange(targ, true, false) ) {
                            if ( targ != parent->Target() ) callme = true;
                            parent->Target(targ);
                            parent->SetTurretAI();
                            parent->TargetTurret(targ);
                            //if I am the capship, go into defensive mode.
                            if (parent == leaderowner) {
                                //get in front of me
                                parent->TurretFAW();
                                c.SetCurrentState(c.fsm->GetYesNode(), NULL, 0);
                                //MatchVelocity(parent->ClampVelocity(vec,true),Vector(0,0,0),true,true,false)
                                //Order * ord = new Orders::FormUp(QVector(position*parent->radial_size,0,fabs(dist)));
                                Order *ord = new Orders::MatchLinearVelocity(parent->ClampVelocity(Vector(0,
                                                                                                          0,
                                                                                                          0),
                                                                                                   true), true, false, true);
                                ord->SetParent(parent);
                                ReplaceOrder(ord);
                                //facing forward
                                ord = new Orders::FaceTarget(false, 3);
                                ord->SetParent(parent);
                                ReplaceOrder(ord);
                            } else {
                                Order *ord = new Orders::FaceTarget(false, 3);
                                ord->SetParent(parent);
                                ReplaceOrder(ord);
                                c.SetCurrentState(c.fsm->GetYesNode(), NULL, 0);
                            }
                        } else
                            c.SetCurrentState(c.fsm->GetNoNode(), NULL, 0);
                        if (fg->directive != last_directive) {
                            Order *lo = leader->getAIState();
                            if (lo || callme) lo->Communicate(c);
                        }
                    }
                } //a is now used for AI, for backward compatibility. do not use for player
            } else if (fg->directive.find("a") != string::npos || fg->directive.find("A") != string::npos) {
                Unit *targ = fg->leader.GetUnit();
                targ = targ != NULL ? targ->Target() : NULL;
                if (targ) {
                    if ( targ->InCorrectStarSystem( _Universe->activeStarSystem() ) ) {
                        CommunicationMessage c(parent, leader, NULL, 0);
                        if ( parent->InRange(targ, true, false) ) {
                            parent->Target(targ);
                            parent->TargetTurret(targ);
                            c.SetCurrentState(c.fsm->GetYesNode(), NULL, 0);
                        } else
                            c.SetCurrentState(c.fsm->GetNoNode(), NULL, 0);
                        if (fg->directive != last_directive) {
                            Order *lo = leader->getAIState();
                            if (lo) lo->Communicate(c);
                        }
                    }
                }
            } else if (fg->directive.find("f") != string::npos || fg->directive.find("F") != string::npos) {
                if (leader != NULL) {
                    if ( leader->InCorrectStarSystem( _Universe->activeStarSystem() ) ) {
                        retval = true;
                        if ( fg->directive != last_directive || (!last_time_insys) ) {
                            last_time_insys = true;
                            CommunicationMessage c(parent, leader, NULL, 0);
                            c.SetCurrentState(c.fsm->GetYesNode(), NULL, 0);
                            //}else {
                            //c.SetCurrentState (c.fsm->GetNoNode(),NULL,0);
                            //}
                            Order               *o           = leader->getAIState();
                            if (o) o->Communicate(c);
                            static float         esc_percent = XMLSupport::parse_float( vs_config->getVariable("AI",
                                                                                                               "Targetting",
                                                                                                               "EscortDistance",
                                                                                                               "10.0") );
                            static float         turn_leader = XMLSupport::parse_float( vs_config->getVariable("AI",
                                                                                                               "Targetting",
                                                                                                               "TurnLeaderDist",
                                                                                                               "5.0") );
                            int                  fgnum       = parent->getFgSubnumber();
                            if ( parent->getFlightgroup() ) {
                                int    tempnum = 0;
                                string nam     = parent->getFlightgroup()->name;
                                int    i       = nam.length()-1;
                                for (; i >= 0; --i) {
                                    char digit = nam[i];
                                    if (digit >= '0' && digit <= '9') {
                                        tempnum *= 10;
                                        tempnum += digit-'0';
                                    } else break;
                                }
                                fgnum += tempnum;
                            }
                            float  left = fgnum%2 ? 1 : -1;
                            double dist = esc_percent*(1+abs(fgnum-1)/2)*left*( parent->rSize()+leader->rSize() );
                            Order *ord  = new Orders::FormUp( QVector( dist, 0, -fabs(dist) ) );
                            ord->SetParent(parent);
                            ReplaceOrder(ord);
                            ord = new Orders::FaceDirection(dist*turn_leader);
                            ord->SetParent(parent);
                            ReplaceOrder(ord);
                        }
                    } else
                        last_time_insys = false;
                    for (unsigned int i = 0; i < suborders.size(); i++)
                        suborders[i]->AttachSelfOrder(leader);
                }
            } else if (fg->directive.find("l") != string::npos || fg->directive.find("L") != string::npos) {
                if (leader != NULL) {
                    if ( leader->InCorrectStarSystem( _Universe->activeStarSystem() ) ) {
                        retval = true;
                        if ( fg->directive != last_directive || (!last_time_insys) ) {
                            last_time_insys = true;
                            CommunicationMessage c(parent, leader, NULL, 0);
//this order is only valid for cargo wingmen, other wingmen will not comply
                            c.SetCurrentState(c.fsm->GetYesNode(), NULL, 0);
                            Order               *o           = leader->getAIState();
                            if (o) o->Communicate(c);
                            static float         esc_percent = XMLSupport::parse_float( vs_config->getVariable("AI",
                                                                                                               "Targetting",
                                                                                                               "EscortDistance",
                                                                                                               "10.0") );
                            static float         turn_leader = XMLSupport::parse_float( vs_config->getVariable("AI",
                                                                                                               "Targetting",
                                                                                                               "TurnLeaderDist",
                                                                                                               "5.0") );
                            int                  fgnum       = parent->getFgSubnumber();
                            if ( parent->getFlightgroup() ) {
                                int    tempnum = 0;
                                string nam     = parent->getFlightgroup()->name;
                                int    i       = nam.length()-1;
                                for (; i >= 0; --i) {
                                    char digit = nam[i];
                                    if (digit >= '0' && digit <= '9') {
                                        tempnum *= 10;
                                        tempnum += digit-'0';
                                    } else break;
                                }
                                fgnum += tempnum;
                            }
/*
   // this does the job for real! "parent" is executor, "leader" is commander

   // moves where you want it to
   // moves flat out in front of parent unit (to allow for tractoring)
                  Order * ord = new Orders::FormUp(QVector(position*parent->radial_size,0,fabs(dist)));
              ord->SetParent (parent);
              ReplaceOrder (ord);
   // faces same direction as leader
   //		  ord = new Orders::FaceDirection(dist*turn_leader);
   // faces opposite direction as leader, as in, stare at me in the face please
                  ord = new Orders::FaceDirection(-dist*turn_leader);
              ord->SetParent (parent);
              ReplaceOrder (ord);
 */
                            int   alternate = fgnum%2 ? 1 : -1;
                            float psize     = parent->radial_size;
                            int   Ypos      = 0;
                            int   Xpos      = 0;
                            int   position  = int( floor( (fgnum%3)*0.5*alternate ) );
//nice square formation, how many of these are you going to have anyway? Max 9, then go back. Should be enough.
                            switch (fgnum%9)
                            {
                            case 0:
                                Xpos = 0;
                                Ypos = 0;
                                break;
                            case 1:
                                Xpos = -1;
                                Ypos = 0;
                                break;
                            case 2:
                                Xpos = 1;
                                Ypos = 0;
                                break;
                            case 3:
                                Xpos = 0;
                                Ypos = -1;
                                break;
                            case 4:
                                Xpos = -1;
                                Ypos = -1;
                                break;
                            case 5:
                                Xpos = 1;
                                Ypos = -1;
                                break;
                            case 6:
                                Xpos = 0;
                                Ypos = 1;
                                break;
                            case 7:
                                Xpos = -1;
                                Ypos = 1;
                                break;
                            case 8:
                                Xpos = 1;
                                Ypos = 1;
                                break;
                            default:
                                Xpos = 0;
                                Ypos = 0;
                            }
                            float dist     = (leader->radial_size+parent->radial_size);
                            float formdist = esc_percent*(1+fgnum*2)*alternate*(dist);
                            //if i am a cargo wingman, get into a dockable position
                            if (parentowner == leader) {
                                Order *ord = new Orders::FormUp( QVector( 1.1*Xpos*psize, 1.1*Ypos*psize, fabs(dist) ) );
                                ord->SetParent(parent);
                                ReplaceOrder(ord);
                                //facing me
                                ord = new Orders::FaceDirection(-dist*turn_leader);
                                ord->SetParent(parent);
                                ReplaceOrder(ord);
                            }
                            //if i am a cargo wingman and so is the player, get into a dockable position with the leader
                            else if ( parentowner && leaderowner && (parentowner == leaderowner) ) {
//float left= fgnum%2?1:-1;
                                Unit  *leaderownerun =
                                    ( leaderowner
                                     == leader ? leader : ( leaderowner == parent ? parent : findUnitInStarsystem(leaderowner) ) );
                                float  qdist         = ( parent->rSize()+leaderownerun->rSize() );
                                Order *ord           =
                                    new Orders::MoveTo(leaderownerun->Position()+Vector(0.5*Xpos*psize,
                                                                                        0.5*Ypos*psize,
                                                                                        0.5*qdist), true, 4);
                                ord->SetParent(parent);
                                ReplaceOrder(ord);
                                //facing it
                                ord = new Orders::FaceDirection(-qdist*turn_leader);
                                ord->SetParent(parent);
                                ReplaceOrder(ord);
                            }
                            //if i am the capship, go into defensive mode
                            else if (parent == leaderowner) {
//// parent->Target(parent);
                                parent->SetTurretAI();
                                TurretFAW(parent);
                                Order *ord = new Orders::MatchLinearVelocity(parent->ClampVelocity(Vector(0,
                                                                                                          0,
                                                                                                          0),
                                                                                                   true), true, false, true);
                                ord->SetParent(parent);
                                ReplaceOrder(ord);
                                if (parent->Target() != NULL) ord = new Orders::FaceTarget(false, 3);
                                else ord = new Orders::FaceDirection(-dist*turn_leader);
                                ord->SetParent(parent);
                                ReplaceOrder(ord);
                            } else {
                                //if i'm not a cargo wingman, just form up somewhat loosely.
                                parentowner = parent;
                                Order *ord =
                                    new Orders::FormUp( QVector(5*Xpos*psize, 5*Ypos*psize, -fabs(formdist)+Ypos*psize+Xpos
                                                                *psize) );
                                ord->SetParent(parent);
                                ReplaceOrder(ord);
                                ord         = new Orders::FaceDirection(dist*turn_leader);
                                ord->SetParent(parent);
                                ReplaceOrder(ord);
                            }
                        }
                    } else
                        last_time_insys = false;
                    for (unsigned int i = 0; i < suborders.size(); i++)
                        suborders[i]->AttachSelfOrder(leader);
                }
            } else if (fg->directive.find("e") != string::npos || fg->directive.find("E") != string::npos) {
                static QVector LeaderPosition = QVector(0, 0, 0);
                if (LeaderPosition.Magnitude() > 0 || leader != NULL) {
                    if ( LeaderPosition.Magnitude() > 0 || leader->InCorrectStarSystem( _Universe->activeStarSystem() ) ) {
                        retval = true;
                        if (LeaderPosition.Magnitude() == 0) //only read the position the first time
                            LeaderPosition = leader->Position();
                        if ( fg->directive != last_directive || (!last_time_insys) ) {
                            last_time_insys = true;
                            CommunicationMessage c(parent, leader, NULL, 0);
//this order is only valid for cargo wingmen, other wingmen will not comply
                            c.SetCurrentState(c.fsm->GetYesNode(), NULL, 0);
                            static float         esc_percent = XMLSupport::parse_float( vs_config->getVariable("AI",
                                                                                                               "Targetting",
                                                                                                               "EscortDistance",
                                                                                                               "10.0") );
                            static float         turn_leader = XMLSupport::parse_float( vs_config->getVariable("AI",
                                                                                                               "Targetting",
                                                                                                               "TurnLeaderDist",
                                                                                                               "5.0") );
                            int                  fgnum       = parent->getFgSubnumber();
                            if ( parent->getFlightgroup() ) {
                                int    tempnum = 0;
                                string nam     = parent->getFlightgroup()->name;
                                int    i       = nam.length()-1;
                                for (; i >= 0; --i) {
                                    char digit = nam[i];
                                    if (digit >= '0' && digit <= '9') {
                                        tempnum *= 10;
                                        tempnum += digit-'0';
                                    } else break;
                                }
                                fgnum += tempnum;
                            }
/*
   // this does the job for real! "parent" is executor, "leader" is commander

   // moves where you want it to
   // moves flat out in front of parent unit (to allow for tractoring)
                  Order * ord = new Orders::FormUp(QVector(position*parent->radial_size,0,fabs(dist)));
              ord->SetParent (parent);
              ReplaceOrder (ord);
   // faces same direction as leader
   //		  ord = new Orders::FaceDirection(dist*turn_leader);
   // faces opposite direction as leader, as in, stare at me in the face please
                  ord = new Orders::FaceDirection(-dist*turn_leader);
              ord->SetParent (parent);
              ReplaceOrder (ord);
 */
                            int   alternate = fgnum%2 ? 1 : -1;
                            float psize     = parent->radial_size;
                            int   Ypos      = 0;
                            int   Xpos      = 0;
                            int   position  = int( floor( (fgnum%3)*0.5*alternate ) );
//nice square formation, how many of these are you going to have anyway? Max 9, then go back. Should be enough.
                            switch (fgnum%9)
                            {
                            case 0:
                                Xpos = 0;
                                Ypos = 0;
                                break;
                            case 1:
                                Xpos = -1;
                                Ypos = 0;
                                break;
                            case 2:
                                Xpos = 1;
                                Ypos = 0;
                                break;
                            case 3:
                                Xpos = 0;
                                Ypos = -1;
                                break;
                            case 4:
                                Xpos = -1;
                                Ypos = -1;
                                break;
                            case 5:
                                Xpos = 1;
                                Ypos = -1;
                                break;
                            case 6:
                                Xpos = 0;
                                Ypos = 1;
                                break;
                            case 7:
                                Xpos = -1;
                                Ypos = 1;
                                break;
                            case 8:
                                Xpos = 1;
                                Ypos = 1;
                                break;
                            default:
                                Xpos = 0;
                                Ypos = 0;
                            }
                            float dist     = (leader->radial_size+parent->radial_size);
                            float formdist = esc_percent*(1+fgnum*2)*alternate*(dist);
                            //if i am a cargo wingman go close for pickup
                            //if i am the capship, go close for pickup
                            if ( (parent->owner == leader->owner) || parent->owner == leader ) {
//float left= fgnum%2?1:-1;
                                float  qdist = ( 1.5*parent->rSize()+1.5*leader->rSize() );
                                Order *ord   =
                                    new Orders::MoveTo(LeaderPosition+Vector(0.5*Xpos*psize,
                                                                             0.5*Ypos*psize,
                                                                             0.5*qdist), true, 4);
                                ord->SetParent(parent);
                                ReplaceOrder(ord);
                                //facing it
                                ord = new Orders::FaceDirection(-qdist*turn_leader);
                                ord->SetParent(parent);
                                ReplaceOrder(ord);
                            }
                            //if i'm not a cargo wingman, IT'S NOT MY PROBLEM.
                            else {
                                parent->owner    = parent;
                                c.SetCurrentState(c.fsm->GetNoNode(), NULL, 0);
                                Flightgroup *leave = new Flightgroup();
                                leave->directive = "b";
                                parent->SetFg(leave, 1);
                            }
                            Order *o = leader->getAIState();
                            if (o) o->Communicate(c);
                        }
                    } else
                        last_time_insys = false;
                    for (unsigned int i = 0; i < suborders.size(); i++)
                        suborders[i]->AttachSelfOrder(leader);
                }
            } else if (fg->directive.find("h") != string::npos || fg->directive.find("H") != string::npos) {
                //VSFileSystem::vs_fprintf (stderr,"he wnats to help out");
                if (fg->directive != last_directive && leader) {
                    if ( leader->InCorrectStarSystem( _Universe->activeStarSystem() ) ) {
                        //VSFileSystem::vs_fprintf (stderr,"%s he wnats to help out and hasn't died\n", parent->name.c_str());
                        Unit *th = NULL;
                        if ( ( th = leader->Threat() ) ) {
                            //VSFileSystem::vs_fprintf (stderr,"he wnats to help out and he has a threat\n");
                            CommunicationMessage c(parent, leader, NULL, 0);
                            if ( parent->InRange(th, true, false) ) {
                                parent->Target(th);
                                parent->TargetTurret(th);
                                c.SetCurrentState(c.fsm->GetYesNode(), NULL, 0);
                            } else
                                c.SetCurrentState(c.fsm->GetNoNode(), NULL, 0);
                            Order               *oo = leader->getAIState();
                            if (oo) oo->Communicate(c);
                        } else {
                            //bool targetted=false;
                            //float mindist;
                            //Unit * un=NULL;
                            th = GetThreat(parent, leader);
                            CommunicationMessage c(parent, leader, NULL, 0);
                            //VSFileSystem::vs_fprintf (stderr,"he wnats to help out against threat %d",th);
                            if (th) {
                                if ( parent->InRange(th, true, false) ) {
                                    c.SetCurrentState(c.fsm->GetYesNode(), NULL, 0);
                                    parent->Target(th);
                                    parent->TargetTurret(th);
//if I am the capship, go into defensive mode.
                                    if (parent == leader->owner) {
                                        //parent->Target(parent);
                                        parent->SetTurretAI();
                                        TurretFAW(parent);
//MatchVelocity(parent->ClampVelocity(vec,true),Vector(0,0,0),true,true,false)
//Order * ord = new Orders::FormUp(QVector(position*parent->radial_size,0,fabs(dist)));
                                        Order *ord =
                                            new Orders::MatchLinearVelocity(parent->ClampVelocity(Vector(0,
                                                                                                         0,
                                                                                                         0),
                                                                                                  true), true, false, true);
                                        ord->SetParent(parent);
                                        ReplaceOrder(ord);
                                        if (parent->Target() != NULL) {
                                            ord = new Orders::FaceTarget(false, 3);
                                            ord->SetParent(parent);
                                            ReplaceOrder(ord);
                                        }
                                    }
                                } else {}
                                //VSFileSystem::vs_fprintf (stderr,"Helping out kill: %s",th->name.c_str());
                            } else
                                c.SetCurrentState(c.fsm->GetNoNode(), NULL, 0);
                            Order *loo = leader->getAIState();
                            if (loo) loo->Communicate(c);
                        }
                    }
                }
            } else if (fg->directive.find("p") != string::npos || fg->directive.find("P") != string::npos) {
                //VSFileSystem::vs_fprintf (stderr,"he wnats to help out");
                bool callme = false;
                if (fg->directive != last_directive && leader) {
                    if ( leader->InCorrectStarSystem( _Universe->activeStarSystem() ) ) {
                        //VSFileSystem::vs_fprintf (stderr,"%s he wnats to help out and hasn't died\n", parent->name.c_str());
                        Unit *th   = NULL;
                        Unit *targ = fg->target.GetUnit();
                        if ( targ && ( th = targ->Threat() ) ) {
                            //VSFileSystem::vs_fprintf (stderr,"he wnats to help out and he has a threat\n");
                            CommunicationMessage c(parent, leader, NULL, 0);
                            if ( parent->InRange(th, true, false) ) {
                                parent->Target(th);
                                parent->TargetTurret(th);
                                c.SetCurrentState(c.fsm->GetYesNode(), NULL, 0);
                                fg->directive = "";
                            } else
                                c.SetCurrentState(c.fsm->GetNoNode(), NULL, 0);
                            Order *oo = leader->getAIState();
                            if (oo) oo->Communicate(c);
                        } else {
                            //bool targetted=false;
                            //float mindist;
                            //Unit * un=NULL;
                            th = GetThreat(parent, targ);
                            CommunicationMessage c(parent, leader, NULL, 0);
                            //VSFileSystem::vs_fprintf (stderr,"he wnats to help out against threat %d",th);
                            if (th) {
                                if ( parent->InRange(th, true, false) ) {
                                    c.SetCurrentState(c.fsm->GetYesNode(), NULL, 0);
                                    if ( th != parent->Target() ) callme = true;
                                    parent->Target(th);
                                    parent->TargetTurret(th);
//if I am the capship, go into defensive mode.
                                    if (parent == leaderowner) {
                                        //parent->Target(parent);
                                        parent->SetTurretAI();
                                        parent->TurretFAW();
//MatchVelocity(parent->ClampVelocity(vec,true),Vector(0,0,0),true,true,false)
//Order * ord = new Orders::FormUp(QVector(position*parent->radial_size,0,fabs(dist)));
                                        Order *ord =
                                            new Orders::MatchLinearVelocity(parent->ClampVelocity(Vector(0,
                                                                                                         0,
                                                                                                         0),
                                                                                                  true), true, false, true);
                                        ord->SetParent(parent);
                                        ReplaceOrder(ord);
                                        if (parent->Target() != NULL) {
                                            ord = new Orders::FaceTarget(false, 3);
                                            ord->SetParent(parent);
                                            ReplaceOrder(ord);
                                        }
                                    }
                                } else
                                    c.SetCurrentState(c.fsm->GetNoNode(), NULL, 0);
                                //VSFileSystem::vs_fprintf (stderr,"Helping out kill: %s",th->name.c_str());
                            } else
                                c.SetCurrentState(c.fsm->GetNoNode(), NULL, 0);
                            Order *loo = leader->getAIState();
                            if (loo) loo->Communicate(c);
                        }
                    }
                }
            }
        }
        last_directive = fg->directive;
    }
    return retval;
}
Damned crap! It still doesn't let me finish; I have to split yet again... So much work...
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: AI re-devlopment thread

Post by chuck_starchaser »

... continuing again ...

Code: Select all

static bool overridable (const std::string &s)
{
    if ( s.empty() ) return true;
    return ( *s.begin() ) != toupper( *s.begin() );
}

extern void LeadMe (Unit *un, string directive, string speech, bool changetarget);
void AggressiveAI::ReCommandWing (Flightgroup *fg)
{
    static float time_to_recommand_wing = XMLSupport::parse_float( vs_config->getVariable("AI",
                                                                                          "Targetting",
                                                                                          "TargetCommandierTime",
                                                                                          "100") );
    static bool  verbose_debug          = XMLSupport::parse_bool( vs_config->getVariable("data", "verbose_debug", "false") );
    if (fg != NULL) {
        Unit *lead;
        if ( overridable(fg->directive) ) {
            //computer won't override capital orders
            if ( NULL != ( lead = fg->leader.GetUnit() ) ) {
                if (float( rand() )/RAND_MAX < SIMULATION_ATOM/time_to_recommand_wing) {
                    if ( parent->Threat() && (parent->FShieldData() < .2 || parent->RShieldData() < .2) ) {
                        fg->directive = string("h");
                        LeadMe(parent, "h", "I need help here!", false);
                        if (verbose_debug)
                            VSFileSystem::vs_fprintf( stderr, "he needs help %s", parent->name.get().c_str() );
                    } else {
                        if ( lead->getFgSubnumber() >= parent->getFgSubnumber() ) {
                            fg->directive = string("b");
                            LeadMe(parent, "b", "I'm taking over this wing. Break and attack", false);
                        }
                    }
                }
            }
        }
    }
}

static Unit * GetRandomNav (vector< UnitContainer >navs[3], unsigned int randnum)
{
    size_t total_size = navs[0].size()+navs[1].size()+navs[2].size();
    if (total_size == 0) return NULL;
    randnum %= total_size;
    if ( randnum >= navs[0].size() ) {
        randnum -= navs[0].size();
        if ( randnum >= navs[1].size() ) {
            randnum -= navs[1].size();
            return navs[2][randnum].GetUnit();
        }
        return navs[1][randnum].GetUnit();
    }
    return navs[0][randnum].GetUnit();
}

static std::string insysString("Insys");
static std::string arrowString("->");
static Unit * ChooseNavPoint (Unit *parent, Unit **otherdest, float *lurk_on_arrival)
{
    static string script = vs_config->getVariable("AI", "ChooseDestinationScript", "");
    *lurk_on_arrival = 0;
    if (script.length() > 0) {
        Unit *ret = NULL;
        UniverseUtil::setScratchUnit(parent);
        CompileRunPython(script);
        ret = UniverseUtil::getScratchUnit();
        UniverseUtil::setScratchUnit(NULL);
        if (ret != NULL && ret != parent)
            return ret;
    }
    StarSystem             *ss                  = _Universe->activeStarSystem();
    StarSystem::Statistics *stats               = &ss->stats;
    float                   sysrel              = UnitUtil::getRelationFromFaction(parent, stats->system_faction);
    static float            lurk_time           = XMLSupport::parse_float( vs_config->getVariable("AI", "lurk_time", "600") );
    static float            select_time         =
        XMLSupport::parse_float( vs_config->getVariable("AI", "fg_nav_select_time", "120") );
    static float            hostile_select_time =
        XMLSupport::parse_float( vs_config->getVariable("AI", "pirate_nav_select_time", "400") );
    static int              num_ships_per_roid  =
        XMLSupport::parse_int( vs_config->getVariable("AI", "num_pirates_per_asteroid_field", "12") );
    bool                    civilian            = FactionUtil::isCitizenInt(parent->faction);
    bool                    hostile             = sysrel < 0;
    bool                    anarchy             = stats->enemycount > stats->friendlycount;
    float                   timehash            = select_time;
    if (hostile && !anarchy) timehash = hostile_select_time;
    unsigned int            firstRand, thirdRand;
    float                   secondRand;
    const unsigned int      maxrand             = 5;
    unsigned int            additionalrand[maxrand];
    if (civilian) {
        firstRand  = vsrandom.genrand_int31();
        secondRand = vsrandom.uniformExc(0, 1);
        thirdRand  = vsrandom.genrand_int31();
        for (unsigned int i = 0; i < maxrand; ++i)
            additionalrand[i] = thirdRand+i;
    } else {
        int                         k     = (int) (getNewTime()/timehash); //two minutes
        string                      key   = UnitUtil::getFlightgroupName(parent);
        std::string::const_iterator start = key.begin();
        for (; start != key.end(); start++)
            k += (k*128)+*start;
        VSRandom                    choosePlace(k);
        firstRand  = choosePlace.genrand_int31();
        secondRand = choosePlace.uniformExc(0, 1);
        thirdRand  = choosePlace.genrand_int31();
        for (unsigned int i = 0; i < maxrand; ++i)
            additionalrand[i] = choosePlace.genrand_int31();
    }
    bool                   asteroidhide   = false;
    if (stats->friendlycount > 0 && stats->enemycount > 0)
        asteroidhide = (secondRand < stats->enemycount/(float) stats->friendlycount)
                       && (secondRand < num_ships_per_roid*stats->navs[2].size()/(float) stats->enemycount);
    bool                   siege          = stats->enemycount > 2*stats->friendlycount; //rough approx
    int                    whichlist      = 1; //friendly
    std::string            fgname         = UnitUtil::getFlightgroupName(parent);
    bool                   insys          =
        (parent->GetJumpStatus().drive == -2) || fgname.find(insysString) != std::string::npos;
    std::string::size_type whereconvoy    = fgname.find(arrowString);
    bool                   convoy         = (whereconvoy != std::string::npos);
    size_t                 total_size     = stats->navs[0].size()+stats->navs[whichlist].size(); //friendly and neutral
    static bool            bad_units_lurk = XMLSupport::parse_bool( vs_config->getVariable("AI", "hostile_lurk", "true") );
    if (hostile && bad_units_lurk) {
        if (anarchy && !siege) {
            whichlist  = 2;
            total_size = stats->navs[0].size()+stats->navs[whichlist].size(); //asteroids and neutrals
        } else {
            whichlist  = 2;
            total_size = stats->navs[whichlist].size(); //just asteroids
        }
    } else if (civilian) {
        if (anarchy || siege) {
            whichlist  = 0;
            total_size = stats->navs[0].size();
        } else if (insys || convoy) {
            whichlist  = 1;
            total_size = stats->navs[1].size(); //don't go to jump point
        }
    }
    if (hostile && ( (anarchy == false && asteroidhide == false) || total_size == 0 ) && civilian == false && bad_units_lurk) {
        //hit and run
        Unit *a = GetRandomNav(stats->navs, firstRand);
        Unit *b = GetRandomNav(stats->navs, thirdRand);
        if (a == b)
            b = GetRandomNav(stats->navs, thirdRand+1);
        if (a != b) {
            int retrycount = maxrand;
            while ( --retrycount > 0
                   && (UnitUtil::getDistance(a, b) < parent->GetComputerData().radar.maxrange*4 || a == b) ) {
                b = GetRandomNav(stats->navs, additionalrand[retrycount]);
            }
            if (retrycount != 0) {
                *otherdest       = b;
                *lurk_on_arrival = lurk_time;
            }
        }
        return a;
    } else {
        if (convoy) {
            std::string srcdst[2] = {fgname.substr(0, whereconvoy), fgname.substr(whereconvoy+2)};
            if ( srcdst[0] == ss->getFileName() ) srcdst[0] = srcdst[1];
            if ( srcdst[1] == ss->getFileName() ) srcdst[1] = srcdst[0];
            size_t      rand8     = thirdRand%8;
            if (thirdRand < 2) {
                vsUMap< std::string, UnitContainer >::iterator i = stats->jumpPoints.find(srcdst[thirdRand]);
                if ( i != stats->jumpPoints.end() ) {
                    Unit *un = i->second.GetUnit();
                    if (un)
                        return un;
                } else {
                    total_size = stats->navs[whichlist].size()+stats->navs[0].size(); //no such jump point--have to random-walk it
                    //maybe one day we can incorporate some sort of route planning
                }
            }
        }
        if (total_size > 0) {
            firstRand %= total_size;
            if ( firstRand >= stats->navs[whichlist].size() ) {
                firstRand -= stats->navs[whichlist].size();
                whichlist  = 0; //allows you to look for both neutral and ally lists
            }
            return stats->navs[whichlist][firstRand].GetUnit();
        }
    }
    return NULL;
}

static Unit * ChooseNearNavPoint (Unit *parent, Unit *suggestion, QVector location, float locradius)
{
    if (suggestion) return suggestion;
    Unit                      *candidate = NULL;
    float                      dist      = FLT_MAX;
    Unit                      *un;
    NearestNavOrCapshipLocator nnl;
    findObjects(_Universe->activeStarSystem()->collidemap[Unit::UNIT_ONLY],
                parent->location[Unit::UNIT_ONLY],
                &nnl);
    return nnl.retval.unit;
    //DEAD CODE
    for (un_iter i = _Universe->activeStarSystem()->getUnitList().createIterator();
         (un = *i) != NULL;
         ++i) {
        if (UnitUtil::isSignificant(un) && un != parent) {
            float newdist = ( location-un->Position() ).Magnitude()-un->rSize()-locradius;
            if (candidate == NULL || newdist <= dist) {
                candidate = un;
                dist      = newdist;
            }
        }
    }
    return candidate;
    //END DEAD CODE
}

bool CloseEnoughToNavOrDest (Unit *parent, Unit *navUnit, QVector nav)
{
    static float how_far_to_stop_moving =
        XMLSupport::parse_float( vs_config->getVariable("AI", "how_far_to_stop_navigating", "100") );
    if (navUnit && navUnit->isUnit() != PLANETPTR) {
        float dist = UnitUtil::getDistance(navUnit, parent);
        if (dist < SIMULATION_ATOM*parent->Velocity.Magnitude()*parent->predicted_priority*how_far_to_stop_moving) return true;
    }
    return ( nav-parent->Position() ).MagnitudeSquared() < 4*parent->rSize()*parent->rSize();
}
volatile Unit *uoif;
class FlyTo : public Orders::MoveTo
{
    float         creationtime;
    UnitContainer destUnit;
public: FlyTo (const QVector &target,
               bool aft,
               bool terminating = true,
               float creationtime = 0,
               int leniency = 6,
               Unit *destUnit = NULL) : MoveTo(target, aft, leniency, terminating)
    {
        this->creationtime = creationtime;
        this->destUnit     = destUnit;
    }
    virtual void Execute ()
    {
        if (parent == uoif)
            printf("kewl");
        MoveTo::Execute();
        Unit        *un      = destUnit.GetUnit();
        if ( CloseEnoughToNavOrDest(parent, un, targetlocation) ) done = true;
        un = NULL;
        static float mintime = XMLSupport::parse_float( vs_config->getVariable("AI", "min_time_to_auto", "25") );
        if (getNewTime()-creationtime > mintime) {
            if (_Universe->AccessCockpit()->autoInProgress() && ( !_Universe->AccessCockpit()->unitInAutoRegion(parent) )
                && ( un = ChooseNearNavPoint(parent, destUnit.GetUnit(), targetlocation, 0) ) != NULL)
                WarpToP(parent, un, true);

            else {
                Unit *playa = _Universe->AccessCockpit()->GetParent();
                if (playa == NULL || playa->Target() != parent || 1)
                    WarpToP(parent, targetlocation, 0, true);
            }
        }
    }
};

static Vector randVector ()
{
    return Vector( (rand()/(float) RAND_MAX)*2-1, (rand()/(float) RAND_MAX)*2-1, (rand()/(float) RAND_MAX)*2-1 );
}

static void GoTo (AggressiveAI *ai,
                  Unit *parent,
                  const QVector &nav,
                  float creationtime,
                  bool boonies = false,
                  Unit *destUnit = NULL)
{
    static bool can_afterburn = XMLSupport::parse_bool( vs_config->getVariable("AI", "afterburn_to_no_enemies", "true") );
    Order      *mt            = new FlyTo(nav, can_afterburn, true, creationtime, boonies ? 16 : 6, destUnit);
    Order      *ch            = new Orders::ChangeHeading(nav, 32, .25f, false);
    ai->eraseType(Order::FACING);
    ai->eraseType(Order::MOVEMENT);
    mt->SetParent(parent);
    ch->SetParent(parent);
    ai->ReplaceOrder(mt);
    ai->EnqueueOrder(ch);
}

void AggressiveAI::ExecuteNoEnemies ()
{
    static float safetyspacing     = XMLSupport::parse_float( vs_config->getVariable("AI", "safetyspacing", "2500") );
    static float randspacingfactor = XMLSupport::parse_float( vs_config->getVariable("AI", "randomspacingfactor", "4") );
    if (nav.i == 0 && nav.j == 0 && nav.k == 0) {
        Unit *otherdest = NULL;
        Unit *dest      = ChooseNavPoint(parent, &otherdest, &this->lurk_on_arrival);
        if (dest) {
            static bool  can_warp_to = XMLSupport::parse_bool( vs_config->getVariable("AI", "warp_to_no_enemies", "true") );
            static float mintime     = XMLSupport::parse_float( vs_config->getVariable("AI", "min_time_to_auto", "25") );
            if (getNewTime()-creationtime > mintime) {
                if (can_warp_to)
                    WarpToP(parent, dest, true);

                else if ( _Universe->AccessCockpit()->autoInProgress() && !_Universe->AccessCockpit()->unitInAutoRegion(parent) )
                    WarpToP(parent, dest, true);
            }
            Vector dir     = parent->Position()-dest->Position();
            Vector unitdir = dir.Normalize();
            if (!otherdest) {
                navDestination = dest;
                dir            = unitdir*( dest->rSize()+parent->rSize() );
                if (dest->isUnit() == PLANETPTR) {
                    float planetpct = UniverseUtil::getPlanetRadiusPercent();
                    dir *= (planetpct+1.0f);
                    dir += randVector()*parent->rSize()*2*randspacingfactor;
                } else {
                    dir *= 2;
                    dir += (unitdir*safetyspacing);
                    dir +=
                        ( (randVector()*randspacingfactor
                           /4)
                         +(unitdir
                           *randspacingfactor) )
                        *( ( parent->rSize() > (safetyspacing/5) ) ? (safetyspacing/5) : ( parent->rSize() ) );
                }
            }
            nav = dest->Position()+dir;
            if (otherdest) {
                nav += otherdest->Position();
                nav  = nav*.5;
            }
#ifdef AGGDEBUG
            std::string fgname    = UnitUtil::getFlightgroupName(parent);
            std::string pfullname = parent->getFullname();
            std::string dfullname = dest->getFullname();
            printf( "%s:%s %s going to %s:%s", parent->name.get().c_str(), pfullname.c_str(), fgname.c_str(),
                   dest->name.get().c_str(), dfullname.c_str() );
            if (otherdest) {
                std::string ofullname = otherdest->getFullname();
                printf( " between %s:%s\n", otherdest->name.get().c_str(), ofullname.c_str() );
            } else printf("\n");
#endif
            GoTo(this, parent, nav, creationtime, otherdest != NULL, otherdest == NULL ? dest : NULL);
        }
    } else {
        if (CloseEnoughToNavOrDest(parent, navDestination.GetUnit(), nav) && lurk_on_arrival == 0) {
            std::string fgname = UnitUtil::getFlightgroupName(parent);
            nav = QVector(0, 0, 0);
            Unit       *dest   = ChooseNearNavPoint( parent, navDestination.GetUnit(), parent->Position(), parent->rSize() );
            if (dest) {
                if ( fgname.find(insysString) == string::npos && dest->GetDestinations().size() > 0
                    && UniverseUtil::systemInMemory(dest->GetDestinations()[0]) ) {
                    parent->ActivateJumpDrive(0);
                    parent->Target(dest); //fly there, baby!
                } else if ( dest->GetDestinations().size() == 0 && false == UnitUtil::isCapitalShip(parent)
                           && UnitUtil::isDockableUnit(dest) ) {
                    //UnitUtil::performDockingOperations(parent,dest,0);//dock there, baby
                    Order *ai = parent->aistate;
                    parent->aistate = NULL;
                    parent->PrimeOrders( new Orders::DockingOps(dest, ai, true, false) );
                } else
                    ExecuteNoEnemies(); //find a new place to go
            } else
                ExecuteNoEnemies(); //no suitable docking point found, recursive call which will take door1
            //go dock to the nav point
        } else if (lurk_on_arrival > 0) {
            lurk_on_arrival              -= SIMULATION_ATOM;
            //slowdown
            parent->Thrust(-parent->GetMass()*parent->UpCoordinateLevel( parent->GetVelocity() )/SIMULATION_ATOM, false);
            parent->graphicOptions.InWarp = 0;
            if (lurk_on_arrival <= 0) {
                nav = QVector(0, 0, 0);
                ExecuteNoEnemies(); //select new place to go
            }
            //have to do something while here.
        } else
            GoTo( this, parent, nav, creationtime, false, navDestination.GetUnit() );
    }
    /*
       Order * ord = new Orders::MatchLinearVelocity (parent->ClampVelocity(Vector (0,0,10000),false),true,true,false);
       ord->SetParent(parent);
       EnqueueOrder (ord);
     */
}

void AggressiveAI::AfterburnerJumpTurnTowards (Unit *target)
{
    AfterburnTurnTowards(this, parent);
    static float jump_time_limit = XMLSupport::parse_float( vs_config->getVariable("AI", "force_jump_after_time", "120") );
    if (jump_time_check == 0) {
        float dist = ( target->Position()-parent->Position() ).MagnitudeSquared();
        if (last_jump_distance < dist || last_jump_time > jump_time_limit) {
            //force jump
            last_jump_time = 0;
            if ( target->GetDestinations().size() ) {
                string dest = target->GetDestinations()[0];
                UnitUtil::JumpTo(parent, dest);
            }
        } else
            last_jump_distance = dist;
    }
}

volatile Unit *uoi;
void AggressiveAI::Execute ()
{
    if (parent == uoi)
        printf("kewl");
    extern double aggfire;
    jump_time_check++; //just so we get a nicely often wrapping var;
    jump_time_check %= 5;
    Flightgroup  *fg                          = parent->getFlightgroup();
    //ReCommandWing(fg);
    double        firetime                    = queryTime();
    static int    pir                         = FactionUtil::GetFactionIndex("pirates");
    if (parent->faction == pir) if (rand() == 0) printf("ahoy, a pirates!");
    FireAt::Execute();
    aggfire += queryTime()-firetime;
    static bool   resistance_to_side_movement =
        XMLSupport::parse_bool( vs_config->getVariable("AI", "resistance_to_side_movement", "false") );
    if (resistance_to_side_movement) {
        Vector       p, q, r;
        parent->GetOrientation(p, q, r);
        float        forwardness              = parent->Velocity.Dot(r);
        Vector       countervelocity          = -parent->Velocity;
        Vector       counterforce             = -parent->NetForce;
        float        forceforwardness         = parent->NetForce.Dot(r);
        if (forceforwardness > 0)
            counterforce = forceforwardness*r-parent->NetForce;
        if (forwardness > 0)
            countervelocity = forwardness*r-parent->Velocity;
        static float resistance_percent       =
            XMLSupport::parse_float( vs_config->getVariable("AI", "resistance_to_side_movement_percent", ".01") );
        static float force_resistance_percent =
            XMLSupport::parse_float( vs_config->getVariable("AI", "resistance_to_side_force_percent", "1") );
        parent->Velocity      += countervelocity*resistance_percent;
        parent->NetForce      += counterforce*force_resistance_percent;
        counterforce           = -parent->NetLocalForce;
        counterforce.k         = 0;
        parent->NetLocalForce += counterforce*force_resistance_percent;
    }
    Unit *target     = parent->Target();
    bool  isjumpable = target ? ( !target->GetDestinations().empty() ) : false;
    if ( !ProcessCurrentFgDirective(fg) ) {
        if (isjumpable) {
            if (parent->GetJumpStatus().drive < 0) {
                parent->ActivateJumpDrive(0);
                if (parent->GetJumpStatus().drive == -2) {
                    static bool AIjumpCheat =
                        XMLSupport::parse_bool( vs_config->getVariable("AI", "always_have_jumpdrive_cheat", "false") );
                    if (AIjumpCheat) {
                        static int i = 0;
                        if (!i) {
                            VSFileSystem::vs_fprintf(stderr, "FIXME: warning ship not equipped to jump");
                            i = 1;
                        }
                        parent->jump.drive = -1;
                    } else {
                        //VSFileSystem::vs_fprintf (stderr,"warning ship not equipped to jump");
                        parent->Target(NULL);
                    }
                } else if (parent->GetJumpStatus().drive < 0) {
                    static bool AIjumpCheat = XMLSupport::parse_bool( vs_config->getVariable("AI", "jump_cheat", "true") );
                    if (AIjumpCheat)
                        parent->jump.drive = 0;
                }
            }
            last_jump_time += SIMULATION_ATOM;
        } else
            last_jump_time = 0;
        if ( (!isjumpable) && interruptcurtime <= 0 && target ) {
//fprintf (stderr,"i");
            ProcessLogic(*logic, true);
        }
        if (!target) {
            logiccurtime -= SIMULATION_ATOM;
            if (logiccurtime < 0) {
                logiccurtime    = 20;
                currentpriority = -FLT_MAX;
                //eraseType (Order::FACING);
                //eraseType (Order::MOVEMENT);
            }
        }
        //if (parent->getAIState()->queryType (Order::FACING)==NULL&&parent->getAIState()->queryType (Order::MOVEMENT)==NULL) {
        if (queryAny(Order::FACING|Order::MOVEMENT) == NULL) {
            if (isjumpable)
                AfterburnerJumpTurnTowards(target);

            else {
                last_jump_distance = FLT_MAX;
                if (target)
                    ProcessLogic(*logic, false);

                else {}
            }
            if (!isjumpable) ExecuteNoEnemies();
        } else {
            if (target) {
                static bool can_warp_to = XMLSupport::parse_bool( vs_config->getVariable("AI", "warp_to_enemies", "true") );
                if ( can_warp_to || _Universe->AccessCockpit()->autoInProgress() )
                    WarpToP(parent, target, false);
                logiccurtime     -= SIMULATION_ATOM;
                interruptcurtime -= SIMULATION_ATOM;
                if (logiccurtime <= 0) {
                    //parent->getAIState()->eraseType (Order::FACING);
                    //parent->getAIState()->eraseType (Order::MOVEMENT);
                    eraseType(Order::FACING);
                    eraseType(Order::MOVEMENT);
                    if (isjumpable) {
                        AfterburnerJumpTurnTowards(target);
                        logiccurtime = logic->maxtime;
                    } else {
                        last_jump_distance = FLT_MAX;
                        ProcessLogic(*logic, false);
                    }
                }
            } else if (queryAny(Order::MOVEMENT) == NULL)
                ExecuteNoEnemies();
        }
    }
#ifdef AGGDEBUG
    VSFileSystem::vs_fprintf(stderr, "endagg");
    fflush(stderr);
#endif
    if (getTimeCompression() > 3) {
        float mag = parent->GetVelocity().Magnitude();
        if (mag > .01) mag = 1/mag;
        parent->SetVelocity( parent->GetVelocity()*( mag*parent->GetComputerData().max_speed()/getTimeCompression() ) );
        parent->NetLocalForce = parent->NetForce = Vector(0, 0, 0);
    }
    target     = parent->Target();
    isjumpable = target ? ( !target->GetDestinations().empty() ) : false;
    if (!isjumpable) {
        if (parent->GetJumpStatus().drive >= 0)
            parent->ActivateJumpDrive(-1);
    }
}

AggressiveAI *DONOTUSEAG = NULL;
This is with the config for the repo; with the config for myself it looks a lot nicer, of course :D

EDIT: The first of the three posts got orphaned in the previous page.
And I'm sorry I had to post the file this way; my pc is still broken, so I got no access to the junction
server; tomorrow I'll probably fix it.
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: AI re-devlopment thread

Post by chuck_starchaser »

By the way, these are my uncrustify configure settings for vs repo format:

Code: Select all

# Uncrustify 0.55
newlines                                 = auto
input_tab_size                           = 8
output_tab_size                          = 8
string_escape_char                       = 92
string_escape_char2                      = 0
indent_columns                           = 4
indent_continue                          = 0
indent_with_tabs                         = 0
indent_cmt_with_tabs                     = false
indent_align_string                      = false
indent_xml_string                        = 0
indent_brace                             = 0
indent_braces                            = false
indent_braces_no_func                    = false
indent_brace_parent                      = false
indent_namespace                         = false
indent_namespace_level                   = 0
indent_namespace_limit                   = 0
indent_extern                            = false
indent_class                             = true
indent_class_colon                       = false
indent_else_if                           = false
indent_var_def_blk                       = 0
indent_var_def_cont                      = false
indent_func_call_param                   = false
indent_func_def_param                    = false
indent_func_proto_param                  = false
indent_func_class_param                  = false
indent_func_ctor_var_param               = false
indent_template_param                    = false
indent_func_param_double                 = false
indent_func_const                        = 1
indent_func_throw                        = 1
indent_member                            = 0
indent_sing_line_comments                = 0
indent_relative_single_line_comments     = false
indent_switch_case                       = 0
indent_case_shift                        = 0
indent_case_brace                        = 4
indent_col1_comment                      = false
indent_label                             = 1
indent_access_spec                       = 1
indent_access_spec_body                  = false
indent_paren_nl                          = false
indent_paren_close                       = 1
indent_comma_paren                       = false
indent_bool_paren                        = false
indent_first_bool_expr                   = false
indent_square_nl                         = false
indent_preserve_sql                      = false
indent_align_assign                      = true
sp_arith                                 = remove
sp_assign                                = ignore
sp_before_assign                         = force
sp_after_assign                          = force
sp_enum_assign                           = ignore
sp_enum_before_assign                    = remove
sp_enum_after_assign                     = remove
sp_pp_concat                             = remove
sp_pp_stringify                          = remove
sp_bool                                  = force
sp_compare                               = force
sp_inside_paren                          = remove
sp_paren_paren                           = remove
sp_balance_nested_parens                 = true
sp_paren_brace                           = force
sp_before_ptr_star                       = force
sp_before_unnamed_ptr_star               = remove
sp_between_ptr_star                      = remove
sp_after_ptr_star                        = remove
sp_after_ptr_star_func                   = force
sp_before_ptr_star_func                  = force
sp_before_byref                          = force
sp_before_unnamed_byref                  = remove
sp_after_byref                           = remove
sp_after_byref_func                      = force
sp_before_byref_func                     = remove
sp_after_type                            = force
sp_template_angle                        = force
sp_before_angle                          = remove
sp_inside_angle                          = force
sp_after_angle                           = remove
sp_angle_paren                           = force
sp_angle_word                            = remove
sp_before_sparen                         = force
sp_inside_sparen                         = remove
sp_inside_sparen_close                   = remove
sp_after_sparen                          = force
sp_sparen_brace                          = force
sp_invariant_paren                       = ignore
sp_after_invariant_paren                 = ignore
sp_special_semi                          = remove
sp_before_semi                           = remove
sp_before_semi_for                       = remove
sp_before_semi_for_empty                 = remove
sp_after_semi                            = add
sp_after_semi_for                        = force
sp_after_semi_for_empty                  = remove
sp_before_square                         = remove
sp_before_squares                        = remove
sp_inside_square                         = remove
sp_after_comma                           = force
sp_before_comma                          = remove
sp_before_ellipsis                       = force
sp_after_class_colon                     = force
sp_before_class_colon                    = force
sp_before_case_colon                     = remove
sp_after_operator                        = remove
sp_after_operator_sym                    = remove
sp_after_cast                            = force
sp_inside_paren_cast                     = remove
sp_cpp_cast_paren                        = remove
sp_sizeof_paren                          = force
sp_after_tag                             = ignore
sp_inside_braces_enum                    = remove
sp_inside_braces_struct                  = remove
sp_inside_braces                         = remove
sp_inside_braces_empty                   = remove
sp_type_func                             = force
sp_func_proto_paren                      = force
sp_func_def_paren                        = force
sp_inside_fparens                        = remove
sp_inside_fparen                         = remove
sp_square_fparen                         = force
sp_fparen_brace                          = force
sp_func_call_paren                       = remove
sp_func_call_user_paren                  = ignore
sp_func_class_paren                      = force
sp_return_paren                          = force
sp_attribute_paren                       = force
sp_defined_paren                         = force
sp_throw_paren                           = force
sp_macro                                 = force
sp_macro_func                            = force
sp_else_brace                            = force
sp_brace_else                            = force
sp_brace_typedef                         = force
sp_catch_brace                           = force
sp_brace_catch                           = force
sp_finally_brace                         = force
sp_brace_finally                         = force
sp_try_brace                             = force
sp_getset_brace                          = ignore
sp_before_dc                             = remove
sp_after_dc                              = remove
sp_d_array_colon                         = ignore
sp_not                                   = remove
sp_inv                                   = remove
sp_addr                                  = remove
sp_member                                = remove
sp_deref                                 = remove
sp_sign                                  = remove
sp_incdec                                = remove
sp_before_nl_cont                        = force
sp_after_oc_scope                        = ignore
sp_after_oc_colon                        = ignore
sp_before_oc_colon                       = ignore
sp_after_send_oc_colon                   = ignore
sp_before_send_oc_colon                  = ignore
sp_after_oc_type                         = ignore
sp_after_oc_return_type                  = ignore
sp_after_oc_at_sel                       = ignore
sp_before_oc_block_caret                 = ignore
sp_after_oc_block_caret                  = ignore
sp_cond_colon                            = force
sp_cond_question                         = force
sp_case_label                            = force
sp_range                                 = ignore
sp_cmt_cpp_start                         = remove
sp_endif_cmt                             = force
align_keep_tabs                          = false
align_with_tabs                          = false
align_on_tabstop                         = false
align_number_left                        = false
align_func_params                        = false
align_same_func_call_params              = false
align_var_def_span                       = 7
align_var_def_star_style                 = 2
align_var_def_amp_style                  = 2
align_var_def_thresh                     = 0
align_var_def_gap                        = 0
align_var_def_colon                      = false
align_var_def_attribute                  = false
align_var_def_inline                     = false
align_assign_span                        = 7
align_assign_thresh                      = 0
align_enum_equ_span                      = 7
align_enum_equ_thresh                    = 0
align_var_struct_span                    = 7
align_var_struct_thresh                  = 0
align_var_struct_gap                     = 0
align_struct_init_span                   = 7
align_typedef_gap                        = 0
align_typedef_span                       = 7
align_typedef_func                       = 0
align_typedef_star_style                 = 2
align_typedef_amp_style                  = 2
align_right_cmt_span                     = 0
align_right_cmt_mix                      = false
align_right_cmt_gap                      = 0
align_right_cmt_at_col                   = 0
align_func_proto_span                    = 0
align_func_proto_gap                     = 0
align_on_operator                        = false
align_mix_var_proto                      = false
align_single_line_func                   = false
align_single_line_brace                  = false
align_single_line_brace_gap              = 0
align_oc_msg_spec_span                   = 0
align_nl_cont                            = true
align_pp_define_gap                      = 0
align_pp_define_span                     = 0
align_left_shift                         = true
align_oc_msg_colon_span                  = 0
align_oc_decl_colon                      = false
nl_collapse_empty_body                   = true
nl_assign_leave_one_liners               = true
nl_class_leave_one_liners                = false
nl_enum_leave_one_liners                 = true
nl_getset_leave_one_liners               = true
nl_func_leave_one_liners                 = true
nl_if_leave_one_liners                   = true
nl_start_of_file                         = remove
nl_start_of_file_min                     = 0
nl_end_of_file                           = force
nl_end_of_file_min                       = 0
nl_assign_brace                          = remove
nl_assign_square                         = ignore
nl_after_square_assign                   = ignore
nl_func_var_def_blk                      = 0
nl_fcall_brace                           = force
nl_enum_brace                            = force
nl_struct_brace                          = force
nl_union_brace                           = force
nl_if_brace                              = remove
nl_brace_else                            = remove
nl_elseif_brace                          = remove
nl_else_brace                            = remove
nl_else_if                               = remove
nl_brace_finally                         = force
nl_finally_brace                         = remove
nl_try_brace                             = remove
nl_getset_brace                          = remove
nl_for_brace                             = remove
nl_catch_brace                           = remove
nl_brace_catch                           = force
nl_while_brace                           = remove
nl_brace_brace                           = force
nl_do_brace                              = remove
nl_brace_while                           = remove
nl_switch_brace                          = force
nl_multi_line_cond                       = false
nl_multi_line_define                     = true
nl_before_case                           = false
nl_before_throw                          = remove
nl_after_case                            = true
nl_namespace_brace                       = force
nl_template_class                        = force
nl_class_brace                           = force
nl_class_init_args                       = force
nl_func_type_name                        = remove
nl_func_type_name_class                  = remove
nl_func_scope_name                       = remove
nl_func_proto_type_name                  = remove
nl_func_paren                            = remove
nl_func_decl_start                       = remove
nl_func_decl_start_single                = remove
nl_func_decl_args                        = remove
nl_func_decl_end                         = remove
nl_func_decl_end_single                  = remove
nl_func_decl_empty                       = remove
nl_fdef_brace                            = force
nl_after_return                          = true
nl_return_expr                           = remove
nl_after_semicolon                       = true
nl_after_brace_open                      = true
nl_after_brace_open_cmt                  = true
nl_after_vbrace_open                     = true
nl_after_vbrace_open_empty               = false
nl_after_brace_close                     = true
nl_after_vbrace_close                    = true
nl_define_macro                          = false
nl_squeeze_ifdef                         = true
nl_before_if                             = remove
nl_after_if                              = remove
nl_before_for                            = remove
nl_after_for                             = remove
nl_before_while                          = remove
nl_after_while                           = remove
nl_before_switch                         = remove
nl_after_switch                          = remove
nl_before_do                             = remove
nl_after_do                              = remove
nl_ds_struct_enum_cmt                    = false
nl_ds_struct_enum_close_brace            = false
nl_class_colon                           = ignore
nl_create_if_one_liner                   = true
nl_create_for_one_liner                  = true
nl_create_while_one_liner                = true
pos_arith                                = lead
pos_assign                               = trail
pos_bool                                 = lead
pos_compare                              = lead
pos_conditional                          = lead
pos_comma                                = trail
pos_class_comma                          = lead
pos_class_colon                          = trail
code_width                               = 128
ls_for_split_full                        = true
ls_func_split_full                       = true
nl_max                                   = 2
nl_after_func_proto                      = 0
nl_after_func_proto_group                = 1
nl_after_func_body                       = 0
nl_after_func_body_one_liner             = 0
nl_before_block_comment                  = 1
nl_before_c_comment                      = 0
nl_before_cpp_comment                    = 0
nl_after_multiline_comment               = false
nl_before_access_spec                    = 0
nl_after_access_spec                     = 0
nl_comment_func_def                      = 0
nl_after_try_catch_finally               = 0
nl_around_cs_property                    = 0
nl_between_get_set                       = 0
eat_blanks_after_open_brace              = true
eat_blanks_before_close_brace            = true
mod_full_brace_do                        = remove
mod_full_brace_for                       = remove
mod_full_brace_function                  = ignore
mod_full_brace_if                        = remove
mod_full_brace_if_chain                  = false
mod_full_brace_nl                        = 2
mod_full_brace_while                     = ignore
mod_paren_on_return                      = remove
mod_pawn_semicolon                       = false
mod_full_paren_if_bool                   = false
mod_remove_extra_semicolon               = true
mod_add_long_function_closebrace_comment = 0
mod_add_long_switch_closebrace_comment   = 0
mod_add_long_ifdef_endif_comment         = 0
mod_add_long_ifdef_else_comment          = 0
mod_sort_import                          = false
mod_sort_using                           = false
mod_sort_include                         = false
mod_move_case_break                      = false
mod_case_brace                           = remove
mod_remove_empty_return                  = true
cmt_width                                = 0
cmt_reflow_mode                          = 0
cmt_indent_multi                         = true
cmt_c_group                              = false
cmt_c_nl_start                           = false
cmt_c_nl_end                             = false
cmt_cpp_group                            = false
cmt_cpp_nl_start                         = false
cmt_cpp_nl_end                           = false
cmt_cpp_to_c                             = false
cmt_star_cont                            = false
cmt_sp_before_star_cont                  = 0
cmt_sp_after_star_cont                   = 0
cmt_multi_check_last                     = true
cmt_insert_file_header                   = ""
cmt_insert_file_footer                   = ""
cmt_insert_func_header                   = ""
cmt_insert_class_header                  = ""
cmt_insert_before_preproc                = false
pp_indent                                = ignore
pp_indent_at_level                       = false
pp_indent_count                          = 1
pp_space                                 = ignore
pp_space_count                           = 0
pp_indent_region                         = 0
pp_region_indent_code                    = false
pp_indent_if                             = 0
pp_if_indent_code                        = false
pp_define_at_level                       = false
and this is my configuration for myself:

Code: Select all

# Uncrustify 0.55
newlines                                 = auto
input_tab_size                           = 8
output_tab_size                          = 8
string_escape_char                       = 92
string_escape_char2                      = 0
indent_columns                           = 4
indent_continue                          = 0
indent_with_tabs                         = 0
indent_cmt_with_tabs                     = false
indent_align_string                      = false
indent_xml_string                        = 0
indent_brace                             = 0
indent_braces                            = false
indent_braces_no_func                    = false
indent_brace_parent                      = false
indent_namespace                         = false
indent_namespace_level                   = 0
indent_namespace_limit                   = 0
indent_extern                            = false
indent_class                             = true
indent_class_colon                       = false
indent_else_if                           = false
indent_var_def_blk                       = 0
indent_var_def_cont                      = false
indent_func_call_param                   = false
indent_func_def_param                    = false
indent_func_proto_param                  = false
indent_func_class_param                  = false
indent_func_ctor_var_param               = false
indent_template_param                    = false
indent_func_param_double                 = false
indent_func_const                        = 1
indent_func_throw                        = 1
indent_member                            = 0
indent_sing_line_comments                = 0
indent_relative_single_line_comments     = false
indent_switch_case                       = 0
indent_case_shift                        = 0
indent_case_brace                        = 4
indent_col1_comment                      = false
indent_label                             = 1
indent_access_spec                       = 1
indent_access_spec_body                  = false
indent_paren_nl                          = false
indent_paren_close                       = 1
indent_comma_paren                       = false
indent_bool_paren                        = false
indent_first_bool_expr                   = false
indent_square_nl                         = false
indent_preserve_sql                      = false
indent_align_assign                      = true
sp_arith                                 = remove
sp_assign                                = ignore
sp_before_assign                         = force
sp_after_assign                          = force
sp_enum_assign                           = ignore
sp_enum_before_assign                    = remove
sp_enum_after_assign                     = remove
sp_pp_concat                             = remove
sp_pp_stringify                          = remove
sp_bool                                  = force
sp_compare                               = force
sp_inside_paren                          = force
sp_paren_paren                           = remove
sp_balance_nested_parens                 = true
sp_paren_brace                           = remove
sp_before_ptr_star                       = force
sp_before_unnamed_ptr_star               = remove
sp_between_ptr_star                      = remove
sp_after_ptr_star                        = remove
sp_after_ptr_star_func                   = force
sp_before_ptr_star_func                  = force
sp_before_byref                          = force
sp_before_unnamed_byref                  = remove
sp_after_byref                           = remove
sp_after_byref_func                      = force
sp_before_byref_func                     = remove
sp_after_type                            = force
sp_template_angle                        = remove
sp_before_angle                          = remove
sp_inside_angle                          = force
sp_after_angle                           = force
sp_angle_paren                           = remove
sp_angle_word                            = remove
sp_before_sparen                         = remove
sp_inside_sparen                         = force
sp_inside_sparen_close                   = force
sp_after_sparen                          = remove
sp_sparen_brace                          = remove
sp_invariant_paren                       = ignore
sp_after_invariant_paren                 = ignore
sp_special_semi                          = force
sp_before_semi                           = remove
sp_before_semi_for                       = remove
sp_before_semi_for_empty                 = force
sp_after_semi                            = add
sp_after_semi_for                        = force
sp_after_semi_for_empty                  = force
sp_before_square                         = remove
sp_before_squares                        = remove
sp_inside_square                         = remove
sp_after_comma                           = force
sp_before_comma                          = remove
sp_before_ellipsis                       = force
sp_after_class_colon                     = force
sp_before_class_colon                    = force
sp_before_case_colon                     = remove
sp_after_operator                        = remove
sp_after_operator_sym                    = remove
sp_after_cast                            = force
sp_inside_paren_cast                     = remove
sp_cpp_cast_paren                        = remove
sp_sizeof_paren                          = remove
sp_after_tag                             = ignore
sp_inside_braces_enum                    = force
sp_inside_braces_struct                  = force
sp_inside_braces                         = force
sp_inside_braces_empty                   = remove
sp_type_func                             = force
sp_func_proto_paren                      = remove
sp_func_def_paren                        = remove
sp_inside_fparens                        = remove
sp_inside_fparen                         = force
sp_square_fparen                         = remove
sp_fparen_brace                          = remove
sp_func_call_paren                       = remove
sp_func_call_user_paren                  = ignore
sp_func_class_paren                      = remove
sp_return_paren                          = remove
sp_attribute_paren                       = remove
sp_defined_paren                         = remove
sp_throw_paren                           = remove
sp_macro                                 = force
sp_macro_func                            = force
sp_else_brace                            = remove
sp_brace_else                            = remove
sp_brace_typedef                         = force
sp_catch_brace                           = remove
sp_brace_catch                           = remove
sp_finally_brace                         = remove
sp_brace_finally                         = remove
sp_try_brace                             = remove
sp_getset_brace                          = ignore
sp_before_dc                             = remove
sp_after_dc                              = remove
sp_d_array_colon                         = ignore
sp_not                                   = remove
sp_inv                                   = remove
sp_addr                                  = remove
sp_member                                = remove
sp_deref                                 = remove
sp_sign                                  = remove
sp_incdec                                = remove
sp_before_nl_cont                        = force
sp_after_oc_scope                        = ignore
sp_after_oc_colon                        = ignore
sp_before_oc_colon                       = ignore
sp_after_send_oc_colon                   = ignore
sp_before_send_oc_colon                  = ignore
sp_after_oc_type                         = ignore
sp_after_oc_return_type                  = ignore
sp_after_oc_at_sel                       = ignore
sp_before_oc_block_caret                 = ignore
sp_after_oc_block_caret                  = ignore
sp_cond_colon                            = force
sp_cond_question                         = force
sp_case_label                            = force
sp_range                                 = ignore
sp_cmt_cpp_start                         = remove
sp_endif_cmt                             = force
align_keep_tabs                          = false
align_with_tabs                          = false
align_on_tabstop                         = false
align_number_left                        = false
align_func_params                        = false
align_same_func_call_params              = false
align_var_def_span                       = 7
align_var_def_star_style                 = 2
align_var_def_amp_style                  = 2
align_var_def_thresh                     = 0
align_var_def_gap                        = 0
align_var_def_colon                      = false
align_var_def_attribute                  = false
align_var_def_inline                     = false
align_assign_span                        = 7
align_assign_thresh                      = 0
align_enum_equ_span                      = 7
align_enum_equ_thresh                    = 0
align_var_struct_span                    = 7
align_var_struct_thresh                  = 0
align_var_struct_gap                     = 0
align_struct_init_span                   = 7
align_typedef_gap                        = 0
align_typedef_span                       = 7
align_typedef_func                       = 0
align_typedef_star_style                 = 2
align_typedef_amp_style                  = 2
align_right_cmt_span                     = 0
align_right_cmt_mix                      = false
align_right_cmt_gap                      = 0
align_right_cmt_at_col                   = 0
align_func_proto_span                    = 0
align_func_proto_gap                     = 0
align_on_operator                        = false
align_mix_var_proto                      = false
align_single_line_func                   = false
align_single_line_brace                  = false
align_single_line_brace_gap              = 0
align_oc_msg_spec_span                   = 0
align_nl_cont                            = true
align_pp_define_gap                      = 0
align_pp_define_span                     = 0
align_left_shift                         = true
align_oc_msg_colon_span                  = 0
align_oc_decl_colon                      = false
nl_collapse_empty_body                   = true
nl_assign_leave_one_liners               = true
nl_class_leave_one_liners                = false
nl_enum_leave_one_liners                 = true
nl_getset_leave_one_liners               = true
nl_func_leave_one_liners                 = true
nl_if_leave_one_liners                   = true
nl_start_of_file                         = remove
nl_start_of_file_min                     = 0
nl_end_of_file                           = force
nl_end_of_file_min                       = 0
nl_assign_brace                          = force
nl_assign_square                         = ignore
nl_after_square_assign                   = ignore
nl_func_var_def_blk                      = 0
nl_fcall_brace                           = force
nl_enum_brace                            = force
nl_struct_brace                          = force
nl_union_brace                           = force
nl_if_brace                              = force
nl_brace_else                            = force
nl_elseif_brace                          = force
nl_else_brace                            = force
nl_else_if                               = remove
nl_brace_finally                         = force
nl_finally_brace                         = force
nl_try_brace                             = force
nl_getset_brace                          = remove
nl_for_brace                             = force
nl_catch_brace                           = force
nl_brace_catch                           = force
nl_while_brace                           = force
nl_brace_brace                           = force
nl_do_brace                              = force
nl_brace_while                           = force
nl_switch_brace                          = force
nl_multi_line_cond                       = false
nl_multi_line_define                     = true
nl_before_case                           = false
nl_before_throw                          = remove
nl_after_case                            = true
nl_namespace_brace                       = force
nl_template_class                        = force
nl_class_brace                           = force
nl_class_init_args                       = force
nl_func_type_name                        = remove
nl_func_type_name_class                  = remove
nl_func_scope_name                       = remove
nl_func_proto_type_name                  = remove
nl_func_paren                            = remove
nl_func_decl_start                       = remove
nl_func_decl_start_single                = remove
nl_func_decl_args                        = remove
nl_func_decl_end                         = remove
nl_func_decl_end_single                  = remove
nl_func_decl_empty                       = remove
nl_fdef_brace                            = force
nl_after_return                          = true
nl_return_expr                           = remove
nl_after_semicolon                       = true
nl_after_brace_open                      = true
nl_after_brace_open_cmt                  = true
nl_after_vbrace_open                     = true
nl_after_vbrace_open_empty               = false
nl_after_brace_close                     = true
nl_after_vbrace_close                    = true
nl_define_macro                          = false
nl_squeeze_ifdef                         = true
nl_before_if                             = remove
nl_after_if                              = remove
nl_before_for                            = remove
nl_after_for                             = remove
nl_before_while                          = remove
nl_after_while                           = remove
nl_before_switch                         = remove
nl_after_switch                          = remove
nl_before_do                             = remove
nl_after_do                              = remove
nl_ds_struct_enum_cmt                    = false
nl_ds_struct_enum_close_brace            = false
nl_class_colon                           = ignore
nl_create_if_one_liner                   = true
nl_create_for_one_liner                  = true
nl_create_while_one_liner                = true
pos_arith                                = lead
pos_assign                               = trail
pos_bool                                 = lead
pos_compare                              = lead
pos_conditional                          = lead
pos_comma                                = trail
pos_class_comma                          = lead
pos_class_colon                          = trail
code_width                               = 128
ls_for_split_full                        = true
ls_func_split_full                       = true
nl_max                                   = 2
nl_after_func_proto                      = 0
nl_after_func_proto_group                = 1
nl_after_func_body                       = 0
nl_after_func_body_one_liner             = 0
nl_before_block_comment                  = 1
nl_before_c_comment                      = 0
nl_before_cpp_comment                    = 0
nl_after_multiline_comment               = false
nl_before_access_spec                    = 0
nl_after_access_spec                     = 0
nl_comment_func_def                      = 0
nl_after_try_catch_finally               = 0
nl_around_cs_property                    = 0
nl_between_get_set                       = 0
eat_blanks_after_open_brace              = true
eat_blanks_before_close_brace            = true
mod_full_brace_do                        = remove
mod_full_brace_for                       = remove
mod_full_brace_function                  = ignore
mod_full_brace_if                        = remove
mod_full_brace_if_chain                  = false
mod_full_brace_nl                        = 2
mod_full_brace_while                     = ignore
mod_paren_on_return                      = remove
mod_pawn_semicolon                       = false
mod_full_paren_if_bool                   = false
mod_remove_extra_semicolon               = true
mod_add_long_function_closebrace_comment = 0
mod_add_long_switch_closebrace_comment   = 0
mod_add_long_ifdef_endif_comment         = 0
mod_add_long_ifdef_else_comment          = 0
mod_sort_import                          = false
mod_sort_using                           = false
mod_sort_include                         = false
mod_move_case_break                      = false
mod_case_brace                           = remove
mod_remove_empty_return                  = true
cmt_width                                = 0
cmt_reflow_mode                          = 0
cmt_indent_multi                         = true
cmt_c_group                              = false
cmt_c_nl_start                           = false
cmt_c_nl_end                             = false
cmt_cpp_group                            = false
cmt_cpp_nl_start                         = false
cmt_cpp_nl_end                           = false
cmt_cpp_to_c                             = false
cmt_star_cont                            = false
cmt_sp_before_star_cont                  = 0
cmt_sp_after_star_cont                   = 0
cmt_multi_check_last                     = true
cmt_insert_file_header                   = ""
cmt_insert_file_footer                   = ""
cmt_insert_func_header                   = ""
cmt_insert_class_header                  = ""
cmt_insert_before_preproc                = false
pp_indent                                = ignore
pp_indent_at_level                       = false
pp_indent_count                          = 1
pp_space                                 = ignore
pp_space_count                           = 0
pp_indent_region                         = 0
pp_region_indent_code                    = false
pp_indent_if                             = 0
pp_if_indent_code                        = false
pp_define_at_level                       = false
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Re: AI re-devlopment thread

Post by klauss »

Code: Select all

bool AggressiveAI::ProcessLogic (AIEvents::ElemAttrMap &logi, bool inter)
{
    //go through the logic.
    bool                                                       retval = false;
Isn't that too much space between bool and retval?
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: AI re-devlopment thread

Post by chuck_starchaser »

Yeah, consider these configs experimental for now. I have really bold vertical alignment settings for like variable names and assignments; that's why you see so much space there; it's aligning it with some other var above or below.
In any case, I made a shell script to reformat a number of sample files to vs format, from that to my format, and again to vs format, and then diff the first and last vs format outputs. That should result in no differences, but there are; and the vast majority appear to be related to alignment settings; so I intend to keep playing around with the configs until I reach the Mecca of null diff. Also, I skipped the whole comments reformatting section, but intend to finish it.
safemode
Developer
Developer
Posts: 2150
Joined: Mon Apr 23, 2007 1:17 am
Location: Pennsylvania
Contact:

Re: AI re-devlopment thread

Post by safemode »

Klauss, the string ops i was considering part of the micro-ops. Since it appears that they dont have much of an effect despite their existence being in the ai code being highly annoying. Ie. Things like string.find() and comparing upper and lower case characters (we control these files that we're reading, why aren't we explicit with a single case?).

That being said, when i look at old profiles i did and i dont see basically anything in AI land anywhere near taking up time, my motivation for optimizing it dwindles. Obviously though, i didn't deal with many common cases.

Making the AI more complicated is thus, an easier argument to make, but keep in mind, The execution of the AI code is shared with the execution of everything else the game does in a physics frame and most of that other stuff is going to take up a chunk of time. Just because the ai doesn't take up time now, doesn't mean it's not taking up all the time we can afford to give it.

A good test to do would be to insert a usleep() in the process logic function in the AI. Then play the game, noting the framerate (either absolutely or just by eye). Then increase the value of usleep until we drop to below 60fps. I'd try this both in normal non-close space flight and around wormholes/stations where lots of units are interacting, and during combat. This should give you an idea of how much time we have available to add to the physics frame via AI.
Ed Sweetman endorses this message.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Re: AI re-devlopment thread

Post by klauss »

safemode wrote:Klauss, the string ops i was considering part of the micro-ops. Since it appears that they dont have much of an effect despite their existence being in the ai code being highly annoying. Ie. Things like string.find() and comparing upper and lower case characters (we control these files that we're reading, why aren't we explicit with a single case?).

That being said, when i look at old profiles i did and i dont see basically anything in AI land anywhere near taking up time, my motivation for optimizing it dwindles. Obviously though, i didn't deal with many common cases.
Again, I will have to profile myself.
In any case, that code is inefficient regardless of whether it's being run often enough to make a dent. AI is really dumb right now, and does little to nothing. So it's taking too much, any amount of time is too much for doing nothing.
But as you said there are some hot spots, like near jump points and big battles, and there things slow down to a crawl. It may be the AI or the physics, I'll profile.
I know unit creation is rather slow, so when something explodes and the game has to create a few dozen crates (with the cargo that was in the destroyed unit) there is a noticeable pause - so not all bottlenecks are AI or physics.
But even if a smart AI takes slightly more than we can afford, I'd be happy to reassign simulation time from other areas to devote to AI. AI is important enough.

So... lets first make a better AI and see how it performs. I'm pretty sure, if it's coded well, it will perform just as well as the current one despite being smarter, and we won't have to worry about doing all those timing tests. But if it comes to it, lets do it after we have a new AI, so we know how much is it worth - you may think a drop in the framerate is unacceptable without seeing the new AI in action, and accept it happily afterwards.
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: AI re-devlopment thread

Post by chuck_starchaser »

@Safemode: You keep thinking that cpu side things affect fps; that's old school, from back in the days before T&L (Transform & Lighting accel). Nowadays, just about everything graphics is done by the gpu; all the cpu does is send meshes and textures to the videocard, once in a blue moon. and position updates and job requests. So you can't use fps as a test of cpu-side overloading. You need a cpu-side metric.

@All: Good news: I have both config sets ready (except for the comments section; couple more hours work). Conversion back and forth is seamless, albeit two anomalies that are definitely bugs in uncrustify (non-fatal), and I managed to get around them using a bash script. Alignments are now very moderate; --only up to a 4-column threshold within a 3-line span. Enough to make things look neater without adding tons of white space.
One of the two issues has to do with blocks of // comment lines under a } line. At each pass of uncrustify, one comment line jumps above the }. My bash script runs uncrustfy in a loop, multiple times, to give slow settling phenomena a chance to sort itself out; just in case... --this particular issue will probably go away after I finish with the comment block formatting settings (I'll probably have it convert multi-line // blocks to C-type comments).
The other issue is an extra space appearing in front of trailing //comments when I format to my settings and back to vs settings; --but not generally; only at two places in all of aggressive.cpp, and I can't tell what's special about them two lines... Anyways, what the bash script does is run uncrustify 10 times with vs settings, 10 times with my settings, then 10 times again with vs settings, and by then any and all issues are settled, and I can reformat back and forth transparently.

What I'm going to suggest we do is the exact opposite of what we were thinking, though: Rather than wait until we work with a file to reformat it, I think reformatting needs to be its own revision; --i.e.: we should avoid mixing formatting and code changes.

So, let me suggest a pilot project for testing:
Let's pick an area where nobody has work in progress (probably the AI), and when you give me the ok I can go in, reformat one file at a time (making sure it make's) and then commit with comment "REFORMAT --BATCH 01".
Well, not just yet; I'm going to finish the comment block configurations first, and post some files for comparisons and feedback.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Re: AI re-devlopment thread

Post by klauss »

chuck_starchaser wrote:What I'm going to suggest we do is the exact opposite of what we were thinking, though: Rather than wait until we work with a file to reformat it, I think reformatting needs to be its own revision; --i.e.: we should avoid mixing formatting and code changes.

So, let me suggest a pilot project for testing:
Let's pick an area where nobody has work in progress (probably the AI), and when you give me the ok I can go in, reformat one file at a time (making sure it make's) and then commit with comment "REFORMAT --BATCH 01".
Well, not just yet; I'm going to finish the comment block configurations first, and post some files for comparisons and feedback.
Yep, never ever mix reformatting with code changes, it makes scanning the diffs for the code changes worse than impossible.

Even if it's two consecutive commits, it's best to keep them separate.

When you're about to reformat a piece of code, you could lock it with "svn lock". I'm not really sure how it works though, you'll have to read the svn book.
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
safemode
Developer
Developer
Posts: 2150
Joined: Mon Apr 23, 2007 1:17 am
Location: Pennsylvania
Contact:

Re: AI re-devlopment thread

Post by safemode »

The tools you are using to format the code has to be cross platform or we wont be able to accept any changes from other OS developers without becoming their proxy.

Code formatting can't be a one time deal and then we go back to everyone doing their own thing. It has to become a rule that we pass any code through the formatter to normalize any patches prior to committing.
Ed Sweetman endorses this message.
safemode
Developer
Developer
Posts: 2150
Joined: Mon Apr 23, 2007 1:17 am
Location: Pennsylvania
Contact:

Re: AI re-devlopment thread

Post by safemode »

chuck_starchaser wrote: So, let me suggest a pilot project for testing:
Let's pick an area where nobody has work in progress (probably the AI), and when you give me the ok I can go in, reformat one file at a time (making sure it make's) and then commit with comment "REFORMAT --BATCH 01".
Well, not just yet; I'm going to finish the comment block configurations first, and post some files for comparisons and feedback.

In svn, this is a branch. Dont beta test stuff in /trunk

Make a branch, do your testing of reformatting and stuff there then once you have a finished product, merge it back to trunk when it's ready to be played with by everyone.
Ed Sweetman endorses this message.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Re: AI re-devlopment thread

Post by klauss »

@safemode: that would work with small changes, but reformatting touches every line. So you can't allow people to touch those files until reformatting is done. Granted, if all you're doing is playing with settings and seeing how it interacts with SVN, then branch away, but if you're actually formatting code and expect to merge back into trunk, you have to prevent changes in trunk since they'll most certainly result in conflicts.

And... formatting actually can be a one-time thing. Then all committers should pretty much respect the rules, and no code would require being reformatted again by automated tools. Minor discrepancies wouldn't really matter, as long as the overall format is respected (say, if you align too much or too little, as long as it's generally aligned and readable).

That's where code review comes in handy, you can review patches by committers that would otherwise simply get committed. Ie: pre-commit review instead of post-commit review, which is harder. And you can catch more than just formatting errors, you can catch actual errors, like logic errors, or bad practice (coding a bubblesort instead of using std::sort for instance).
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
safemode
Developer
Developer
Posts: 2150
Joined: Mon Apr 23, 2007 1:17 am
Location: Pennsylvania
Contact:

Re: AI re-devlopment thread

Post by safemode »

klauss wrote:@safemode: that would work with small changes, but reformatting touches every line. So you can't allow people to touch those files until reformatting is done. Granted, if all you're doing is playing with settings and seeing how it interacts with SVN, then branch away, but if you're actually formatting code and expect to merge back into trunk, you have to prevent changes in trunk since they'll most certainly result in conflicts.

And... formatting actually can be a one-time thing. Then all committers should pretty much respect the rules, and no code would require being reformatted again by automated tools. Minor discrepancies wouldn't really matter, as long as the overall format is respected (say, if you align too much or too little, as long as it's generally aligned and readable).

That's where code review comes in handy, you can review patches by committers that would otherwise simply get committed. Ie: pre-commit review instead of post-commit review, which is harder. And you can catch more than just formatting errors, you can catch actual errors, like logic errors, or bad practice (coding a bubblesort instead of using std::sort for instance).
Conflicts happen. If all you're doing is running a formatter over something, then it's trivial to use their copy (trunk) and then re-run your formatter on it in your working dir and commit back to your branch and then merge.

Why is doing something like this in a branch (which is purposely for large scale changes) less logical than locking trunk ? Either it will be an extended period of time between the start of committing the changes to the end, in which case you should be working in a branch, or it will be a short single merge in which case what are the chances you are going to be about to merge and someone is going to make a commit? That's like winning the lottery.

Branches aren't going to bite. And they let you do the whole source tree without having to rush and allows others to at least review a bit before you taint the trunk. Also lets you catch your own muck ups. There's absolutely no reason not to be committing something like to a branch first other than laziness in learning the ins and outs of merging.

edit: Also, we dont get that much traffic in terms of people making commits. The problem is and always has been how various editors display and write tabs. Tabs are highly customizeable, and as such, what looks nice on your screen, looks like crap everywhere else. If i mix my setup of turning tabs into spaces and making it 3 spaces for each tab, with a file that has real tabs then we're going to quickly return to files that look like aggressive.cpp. If we want to go through the trouble of formatting every file, then we should make sure that the effort isn't wasted and make sure all the code committed has been through the same sanitizer.

Like i said before, i dont care about personal brace placement issues or any other aspect of how a person wants to write their code. I just care that tabs are uniform. No matter what uniform format that may be, it should be the one thing we are setting in stone if we're bothering to do this at all, since it's the thing that controls the flow of the source the most and it's the most non-uniform aspect of text formatting across editors. And it can be much harder than just a visual check to see if a file has the correct indentation, since if the editor you are viewing in happens to make tabs the same length as the standard and say we make our standard convert tabs to spaces then it becomes very annoying to verify that the patch has converted it's tabs to spaces. etc etc.
Ed Sweetman endorses this message.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Re: AI re-devlopment thread

Post by klauss »

safemode wrote:Conflicts happen. If all you're doing is running a formatter over something, then it's trivial to use their copy (trunk) and then re-run your formatter on it in your working dir and commit back to your branch and then merge.
Hm... makes sense.
safemode wrote:There's absolutely no reason not to be committing something like to a branch first other than laziness in learning the ins and outs of merging.
I'm not a fan of per-author branches (I know you are, since there's a safemode branch ;-) ), but I do use branches a lot. They're great.
safemode wrote:edit: Also, we dont get that much traffic in terms of people making commits. The problem is and always has been how various editors display and write tabs. Tabs are highly customizeable, and as such, what looks nice on your screen, looks like crap everywhere else. If i mix my setup of turning tabs into spaces and making it 3 spaces for each tab, with a file that has real tabs then we're going to quickly return to files that look like aggressive.cpp. If we want to go through the trouble of formatting every file, then we should make sure that the effort isn't wasted and make sure all the code committed has been through the same sanitizer.
Rather I'd pester people that have their editor set up the wrong way.
It's simple: use spaces. All spaces. No tabs. Then what you see is what you get.
People should learn how to use their editor of choice, creating a whole workflow assuming people can't learn how to use their editor doesn't make sense IMO.

Mistaken commits can be fixed with the sanitizer.
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
safemode
Developer
Developer
Posts: 2150
Joined: Mon Apr 23, 2007 1:17 am
Location: Pennsylvania
Contact:

Re: AI re-devlopment thread

Post by safemode »

Well that's the thing, Not all editors have the ability to convert tabs to spaces, in fact i would venture to say that most do not.


As for the branches thing, if you're gonna do frequent commits, and those commits sometimes get large, then it pays to keep an author branch. If what you mostly do is one liners or a file here and there, then no, keeping your own branch is more work than it's worth. But we're all talking about refactoring code, reformatting code, making sweeping changes to numerous files. That kind of stuff lends itself to branch work, and helps keep the trunk sane while you dont have to work your code around the trunk's schedule and more importantly, nobody else has to work around your schedule.

in the case of reformatting where you can't commit the files all sequentially at once, I would split them up by directory so you can merge them back to trunk every so many files. There's no need to wait until the whole thing is done, while at the same time, there is no need to lock trunk and thus interfere with other people who happen (doubtful as it may be) from making unrelated commits.
Ed Sweetman endorses this message.
Post Reply