[BtS-3.13] Combined Arms Stack Attack

I don't understand how the stacked combat works. Are all the units resolving attacks against each other at the same time, or does the stack act as a single unit with traits based on the units it's made up of? Would the results be any different if you attacked a stack with a stack of 10 horse archers than if you attacked the same stack with 1 horse archer at a time for 10 times? Sorry I don't seem to be getting this, but I don't have a computer that can run civ on it at the moment so I can't test it myself.
 
Yes the results would be different.

Basically, whilst the stack attacks together, it's still "best attacker" versus "best defender", except that they are all done together. The biggest change is that any auxillery unit will perform a supporting shot first. So defenders archers, bombard and air units strike the approaching attackers, the attackers auxillery units will respond, and then the mellee units will perform combat.

My changes (for the whole of my DCM) revolve around making combined arms more important.
 
So does that mean that best attacker attacks best defender, second-best attacker attacks second-best defender, etc. down the line?

Yes, that's correct.

And any auxillery unit which already does a support / cover mission during the battle can also participate in the main part of the battle.
 
Shoot, such a letdown. Here I was hoping you actually made all of the units participate in one big melee. That's exactly what I need to make my Frontier Awaits mod's combat work. All I really have to do is interrupt the c++ code when the player tries to initiate combat and get the python to resolve it instead.
 
Shoot, such a letdown. Here I was hoping you actually made all of the units participate in one big melee. That's exactly what I need to make my Frontier Awaits mod's combat work. All I really have to do is interrupt the c++ code when the player tries to initiate combat and get the python to resolve it instead.

Good luck with that. I've been trying to 3 years. :)
 
Good luck with that. I've been trying to 3 years. :)

Heh, do you know if it's possible to create new "callbacks", or are we stuck with the ones that exist already? That's what I should probably try next... Steal an existing callback and use that instead.

Right now I tried interjecting this code into things, once a defender and attacker has been decided upon (and they're pointed at each other and all, it happens right before CvMissionDefinition kMission;). Unfortunately it crashes, and I'm rather stumped as to why. If my declaration or passing of arguments was the case, I'd tinker with that. If the callback isn't defined elsewhere in the code (or is embedded into the EXE), then I'd work around that. But for now, I don't know what the case is.

Anyway, here's what I have so far:
Code:
        if (1)
        {
            CyUnit* pyAttacker = new CyUnit(this);
            CyUnit* pyDefender = new CyUnit(pDefender);

            CyArgsList argsList2; // XXX
            argsList2.add(pyAttacker);
            argsList2.add(pyDefender);
            long lResult=0;
            gDLL->getPythonIFace()->callFunction(PYGameModule, "customCombat", argsList2.makeFunctionArgs(), &lResult);

            delete pyAttacker;
            delete pyDefender;

            if (lResult == 1)
            {
                return;
            }
        }

The python code should be irrelevant, as it doesn't produce an exception, but the function called basically assembles a list of all of the attackers and all of the defenders and randomly picks a defender to die. Sure, a little unbalanced for the attacking side, but it's just a placeholder.

Where I more skilled with c++, this wouldn't be all that difficult, but I'm just dead set on using python because the only dynamic memory structuring available in c++ (as in, storing an arbitrary number of ships) is a bit beyond my comprehension and requires like 100 lines of code just to manipulate. Python it's just.. "untlist.append(unit)". And then you go... unitlist[SorenRand(len(unitlist))].kill and boom, a random unit is killed. :)
 
Where I more skilled with c++, this wouldn't be all that difficult, but I'm just dead set on using python because the only dynamic memory structuring available in c++ (as in, storing an arbitrary number of ships) is a bit beyond my comprehension and requires like 100 lines of code just to manipulate. Python it's just.. "untlist.append(unit)". And then you go... unitlist[SorenRand(len(unitlist))].kill and boom, a random unit is killed. :)

It's actually that easy in the SDK too. Just use the Firaxis functions. :) Which, are the same as the python setup ones. ;)

Oh, when I said "good luck" in getting a stack attack method such as your idea going, I truelly meant. Even Firaxis couldn't get it to work.

So I went the next best thing. Since my goal was to blur the domains so there wasn't the harsh "land vs land only" and "air vs air only" method, I went the path of all domains being able to combat all other domains. Which is what occurs in CASA. "Combined Arms Stack Attack" is where ALL domains can work together in one battle. No more, use air first, then naval then land. Just stack it up baby and fight! :)
 
What do you mean use the firaxis functions? If there are some built-in tools for handling dynamic memory (so that I can build a list of all of the units in a stack and their promotions and a bunch of other misc data) then I'd be happy to do it. Now, the graphics might not work, but I consider that a secondary objective.

Since it's going to be done in the SDK, I've already overwritten the combat function. At least, partially. The defender is automatically killed. It's not quite a random person in the defender's stack, but it's a start. The camera seems to get stuck on the battle though... I guess I overdid it. :)
 
What do you mean use the firaxis functions? If there are some built-in tools for handling dynamic memory (so that I can build a list of all of the units in a stack and their promotions and a bunch of other misc data) then I'd be happy to do it. Now, the graphics might not work, but I consider that a secondary objective.

Since it's going to be done in the SDK, I've already overwritten the combat function. At least, partially. The defender is automatically killed. It's not quite a random person in the defender's stack, but it's a start. The camera seems to get stuck on the battle though... I guess I overdid it. :)

There's heaps of stuff in CLinkList for building and using lists.
Declaration: CLinkList<int> variable;

As to the graphics, yes you can make it all work with no graphic animations (that is the exact spot that the solution fails) but that's the whole point of having stack attack. It looks cool. I have done all of this (years ago) and no one will touch the mod without a graphic solution. I couldn't get it to work, Firaxis couldn't get it to work, so I went the path of the next best thing.

Trust me, I've been through all of this. The fail spot is the animations. GameBryo does not clean out its animations well enough for this feature, and unfortunately you end up tearing the screen then memory alloc failures. :(
 
Memory alloc failures? I really appreciate your help here, but you keep feeding me more questions! How does overwriting the combat model mess up the memory allocation/management?

Though I'm pretty sure the answer is no, are the animation functions in the DLL? That is, could we call them manually?

If not, it might be possible to, by use of a bit of a hack, create phantom units. When you attack, two units are created, one with a promotion that makes it automatically the "Best defender", and these two units duke it out for the visual effects. If at all possible, make the damage the maximum so they only shoot once. Then damage is assigned to the real units, and two more phantom units are created and they duke it out. By spawning phantom units with only partial health, the illusion can be made that different units are taking their turns stepping up to the plate to fight, then moving into the back lines so other units could fight.

Edit: I finally managed to get an intermediary combat thing working. Now the starting planetary defense ship can take out a pirate omega starbase! And the animations worked just fine. The next step is to make it kill a random unit in a stack.
 
Animations are handled by GameBryo my friend. But I'll leave the exploring to you. :)
 
The way the unit things is handled is a bit weird. Changedamage() will accomplish the goal, but kill() crashes the game. Changedamage() calls setdamage() (but curiously does not call it with 3 arguments, as setdamage()'s declaration suggests). Setdamage(), if it is the proper function, does indeed check to see if the unit has suffered more damage than it has hit points, and if so, calls to kill() the unit. Either something is happening in setdamage() that I'm not understanding, or the real setdamage (the one that takes 2 arguments rather than 3) is not in the CvUnit.cpp file.

And I'm still trying to wrap my head around the linked lists used. I see examples of it being used, but I'm also see some values being referenced. I guess I'll understand it eventually. The main key is I need to pull out stuff randomly from the list to do this.
 
Is this available for patch 3.19
I want it so much but I have 3.19
 
Back
Top Bottom