Vincentz Infinite Projects [VIP MOD]

ok,
seems i have merged the mod successfully.
i made plenty of tests and situations.

observations:

--i like that siege units can attack units in a city that has +% city defense - thats a great idea.
--siege immunity - i guess that if theres 2 catapults in a stack and another enemy catapult attacks that unit, the second one in the stack wont get collateral
--the strike back - great idea, but has draw backs - the chances for it should be lowered , allot, i saw a situation where 1 catapult defended vs many attacking catapults. but still cool.

--settings:
giving siege unit air combat limit - 50-75 - will make sure, you cant bomb your way to victory, better that siege wont be able to destroy units,
cause you can get an army of siege , defend them, and clean out cities.

<iCollateralDamage>100</iCollateralDamage> : this draws power from the aircombat? a percentage of it?
<iCollateralDamageLimit>10</iCollateralDamageLimit> this limits the above?

i made siege not to be able to capture cities.
and removed their pillage.

i think ill give some units the target tag, so they will target first siege.

need to be careful not make siege over powered units.

code questions:

if (getDomainType() == DOMAIN_LAND && canRangeStrike() && baseCombatStr() <= airBaseCombatStr())

this part from the git - i guess you added the option for units with ranged to be able to attack regularly? with regulate combat? if their combat is higher then air?


***
i do hope my merge is ok, since i didnt pull it form the mod part, but from your master git.
some functions i left out due to kmod stuff...odds and something....need help with those parts.

but all and all, it seems to be working.
awesome.
 
Last edited:
i never used espionage before either, but that was because it was too expensive.
Given the modifiers to Research vs Espionage is much higher (especially early on), each beaker uses much less commerce than EPs.
Then the cost of steal tech mission was very high as well, so it actually cost more commerce per tech to steal than to research, and topping it off there was the cost of the spy, the 5 rounds to lower cost, and the travelling to enemy city and risk of getting caught getting there and while performing the mission, and finally the spy magically jumped back to the capital, and had to move again. And I almost forgot that EPs where civ specific ;)

All in all the vanilla steal tech was a very bad deal. I changed a lot of it, making it cheaper (it should be), and the spy is stuck on the city after mission (with risk of getting caught) for a couple of rounds, and the EPs being taken from a general pool instead of civ specific (but can, with latest changes get an advantage with the weight system) and get XP and promotions doing missions. With all the changes, espionage has gone from being "nah" to probably my favorite part of the game. Noted that I use a difficulty level where I'm almost always behind in tech'ing atleast until late industrial / early modern era.
 
ok,
seems i have merged the mod successfully.
i made plenty of tests and situations.

observations:

--i like that siege units can attack units in a city that has +% city defense - thats a great idea.
Iirc I made it so the damage is lowered depending on the % city defense. So attacking a unit in a city with 50% defense, would reduce the damage done by 50%
--siege immunity - i guess that if theres 2 catapults in a stack and another enemy catapult attacks that unit, the second one in the stack wont get collateral
Sieges are immune to collateral in vanilla iirc
--the strike back - great idea, but has draw backs - the chances for it should be lowered , allot, i saw a situation where 1 catapult defended vs many attacking catapults. but still cool.
Im thinking about changing it, so a siege can only make 1 strikeback. It used to be like that, but I changed it to multiple. But it started to annoy me when coming with 5 sieges to a city that have 1, and ending up with 5 damaged sieges and possible no damage to enemy.

--settings:
giving siege unit air combat limit - 50-75 - will make sure, you cant bomb your way to victory, better that siege wont be able to destroy units,
cause you can get an army of siege , defend them, and clean out cities.
That is a personal preference and you are absolutely free to modify and do anything you like ;)

<iCollateralDamage>100</iCollateralDamage> : this draws power from the aircombat? a percentage of it?
iirc this is the % of the normal damage that collateral units suffer
<iCollateralDamageLimit>10</iCollateralDamageLimit> this limits the above?
this is the number of units that gets collateral. iirc (I use that term a lot, because I have a bad memory ;)) I randomized that between 0 and x.

i made siege not to be able to capture cities.
and removed their pillage.

i think ill give some units the target tag, so they will target first siege.

need to be careful not make siege over powered units.
Absolutely. iirc I have lowered the damage done by vanillas "suicide sieges", so you would need ALOT of sieges to capture a well defended city.
I dont think that they are overpowered in VIP, though I definitely need them when capturing cities. I do sometimes obliterate single wounded units with a stack of 5-8 sieges though ;)


***
i do hope my merge is ok, since i didnt pull it form the mod part, but from your master git.
some functions i left out due to kmod stuff...odds and something....need help with those parts.

but all and all, it seems to be working.
NICE! Im very happy to hear, and good job. Im not very good at commenting my code, so Im happy to hear it wasnt "Mission Impossible" :)
awesome.
 
OH nice thanks for the comments!

first - thanks for letting me use you code!

city defense - ok - i guess due to the defense i didnt see damage. i think the code is in cvunit. i guess ill do more tests.
range back - limit of one is pretty cool - tips on where to set it in the code? i thought of for now disable it via the xml option.
<iCollateralDamageLimit>10</iCollateralDamageLimit> - i always get confused with those.

"I do sometimes obliterate single wounded units with a stack of 5-8 sieges though" - thats quite ok i think, why should range units , should be able to destroy some . matter of preference .

"NICE! Im very happy to hear, and good job. Im not very good at commenting my code, so Im happy to hear it wasnt "Mission Impossible" :)"
:) well, i owe tons to f1rpo, he really elevated my skill, indirectly and directky and he helps so much.


2 more question : you have given multiple unit_ai's i saw to catapult for example, while vanilla had 2, do you suggest i should also? whats the benefactor?
i removed 2 things - movement multiplier you added somewhere - i think after bombard for units to finish move()
and i removed the delay death something both in the ranged and the strike back -
unofficial patch removed it also as an oos for mp issue.

thanks again.
 
Last edited:
[...] All in all the vanilla steal tech was a very bad deal.
Also in terms of usability, it's an unreasonable number of hoops to jump through: One needs to determine/ guess how many espionage points a tech will cost, increase the espionage slider, set the espionage weights so that all or almost all points are gathered against the proper target (perhaps write down the old weights for later), play for a few turns without forgetting about the whole thing, send a Spy unit (or better multiple because of the failure chance) ahead of time and set the slider and espionage weights back to their original values in the end. Well, one can probably get used to it ...

Having reviewed some of the code that keldath merged: The getActiveTeam calls here look like errors:
CvUnit.cpp#L12551
Will go out of sync in multiplayer and, in singleplayer, the active team is simply the human team. I think the goal is to allow attacked units to strike back. There isn't really a function that says whose player's turn it is; probably because that wouldn't work with simultaneous turns. I'd try adding a bool parameter (sth. like "bStrikeBack") to CvUnit::canRangeStrike and CvUnit::canRangeStrikeAt so that the pDefender->canRangeStrikeAt call in CvUnit::rangeStrike can use that parameter to tell the canRangeStrike functions not to check attackMade.
 
"Will go out of sync in multiplayer "
humm, bad...
i hope you can bypass it.
is this souley due to strike back?

also check my PM for you, i hope you checked the latest code merge i did (folder dev --> 2.36-12.adv096)

gluck!

i ran some tests with the code, 2 700 games. had no issues, ai seem to use the siege very well, from what i saw, there were wars and lots of action.
 
hi guys,

althought i wrote this in PM to f1rpo - i had some thoughts :

1. strike back - it is similar, to the ranged attack , wouldn't it be good to make a function out of it so both the ranged and the strike back would use it both? just an efficiency thought i had.
2. the thing that bothers me most now is the issue with oos that you mentioned.
i guess, that strike back, as it is now, probably Will cause oos.
so , the bool param you spoke of - am i right that it would be something like the bonus converter thing that you made for me there? not to loop it?

i had thought of maybe another way to have this cool strike back feature -
instead of calling for the defender to actually commit an attack, and run the whole thing again -
why not just cause damage to the attacker,
based on the defender definitions:
right after the attack is carried :
if enemy not dead -
and if airrange > 0 (or i guess the function - canranged()
read pdefender : aircombat, , hp + random number (using vincentz ranged_dice)
and just subtract if, from the attacker and throw the messages.)
i guess there wont be a need to know who is the getteam/player or to check for the attackmadeAl. cause all the info comes from the pdefender.
perhaps there wont be animation, or a delay or that, ...its the effect it self thats matters
plus, i guess this process would be faster that issuing , a secondary attack of the enemy.

what do you think?
i have no idea how to write this :)
 
so , the bool param you spoke of - am i right that it would be something like the bonus converter thing that you made for me there? not to loop it?
It looks like you're right that the counterstrikes mostly have their own code separate from CvUnit::rangeStrike. Probably some redundancy there, which isn't nice. Anyway, as it is, rangeStrike calling itself all over (infinite recursion) isn't a concern. It's just a matter of rangeStrike calling canRangeStrikeAt on the attacker (madeAttack needs to be checked) and then on the defender for the counterstrike – madeAttack mustn't be checked. This should do (not tested though):
Spoiler :
Code:
// CvUnit.h
bool canRangeStrikeAt(const CvPlot* pPlot, int iX, int iY, bool bStrikeBack = false) const;
bool canRangeStrike(bool bStrikeBack = false) const;
// CvUnit.cpp
bool CvUnit::canRangeStrikeAt(const CvPlot* pPlot, int iX, int iY, bool bStrikeBack) const
{
   if (!canRangeStrike(bStrikeBack))
      return false;
// ...
bool CvUnit::canRangeStrike(bool bStrikeBack) const
{
   //if (!bStrikeBack && isMadeAllAttacks()) // DotO
   if (!bStrikeBack && !isBlitz() && isMadeAttack())
       return false;
   if (!bStrikeBack && getMoves() > 0 && !canMove())
       return false;
// ...
bool CvUnit::rangeStrike(int iX, int iY)
{
// ...
   if (GC.getDefineINT("RANGESTRIKE_RETURN_FIRE") == 1)
   {
      if (!pDefender->canRangeStrikeAt(pDefender->plot(), getX(), getY(), true))
      {
 
hey,
vincent i hope you dont mind we are talking about his here ..:)

rangeStrike calling itself all over (infinite recursion)
same as in the bonus converter...
i see your aim.

so the oos would have occurred due to this loop / inability to find which team is active.

// CvUnit.h
bool canRangeStrikeAt(const CvPlot* pPlot, int iX, int iY, bool bStrikeBack = false) const;
bool canRangeStrike(bool bStrikeBack = false) const;

i thought it would be looking like this,
thought about it during the day,
and even began to write some variable that would have been passed along the functions, instead of being globally,which ofc is not best :)

seems about right your code.

edit:
does your syntax:
pDefender->plot(), this->plot()->getX(), this->plot()->getY(),true)
is
==
pDefender->plot(), getX(), getY(),true)

ok so great,
ill update the code.

Probably some redundancy there, which isn't nice
i will set it as homework for me later on, to make it as a separated function :)

thanks f1rpo, as usual.
 
Last edited:
Alot of the stuff I put in the gamecore was done before I learned how to program. I had basically no idea why I did the stuff I did, but was lucky most of the times ;)
Other times it was just "oh god, what on earth did I do there"...
Like this one I just caught:
Wanted to make a softcap on experience after upgrade (I hated when I had a really experienced unit and then when upgrading, it was never going to get more promotions again, due to the experience cut).
However the softcap should increase along the eras, and made this:
int MaxXPEra = GC.getDefineINT("MAX_EXPERIENCE_AFTER_UPGRADE") * GET_PLAYER(getOwnerINLINE()).getCurrentEra();
pUpgradeUnit->setExperience((pUpgradeUnit->getExperience() - MaxXPEra / 2 ) + MaxXPEra);
instead of the original
pUpgradeUnit->setExperience(GC.getDefineINT("MAX_EXPERIENCE_AFTER_UPGRADE"));

all is fine, though I started to wonder why the units got MORE xp after upgrading, and looking at the code was one of those "oh god!" moments.
the parenthesis behind the /2 should be before the /2....
so a unit with 20 xp in 4th era would get 20 - 4*3 / 2 + 4*3 = 26xp (with 3 being Max_XP_afterupgrade)
where it really should have been (20 - 4*3) / 2 + 4*3 = 18xp....
duh!!!

One day when I have the time and energy, I will go through what I have made and do some refactoring ;)
Especially the rangestrike could do some changes, as Im not all to happy with it. So if you come up with a good solution for it, please share, and if possible, isolate the code :)
Though I dont know how many of us modders are left, and are there any players left to play the mods? In two weeks time it is 14 years since civ4 was released ;)
 
Hey,
Well, im here since 2005, daily basis...
Our numbers are diminishing, but, look at civ3, its alive.

I just now begining to explode my programming skills in cpp. (im a js dev).

From what i explored your range,, its quite nice.
I changed some and f1rpo helped as well.
I addes also ui info.
I will merge you the code once im done.

Civ4 lives on, unless civ6 willl have mods for ai such as 4. I dont see my self too adandon civ4,, best game, 14 days after.
 
Btw, I think I found a balanced solution to the Strikeback, As long as the backstriker have movement points, it can fire back, but will use MP when backstriking. This does ofcourse makes more sense in my mod where units have 5-15 mp, but perhaps it can be half MP if using vanilla movement.
So something like this (havent tested though ;))

PHP:
        if (pDefender != NULL && pDefender-> movesLeft() > GC.getMOVE_DENOMINATOR())
        {
            pDefender->changeMoves(GC.getMOVE_DENOMINATOR());

edit: reduces the cost for the backstriker to 1 mp, as it is "standing still and returning fire" so it shouldnt cost too much. Also better for balance.
 
Last edited:
Interesting,
If you can share here the part of the code would be nice.

I am thinking about removing the bombard damage from the ranged that you added.
Im going for the same setup as air missions:
One for unit strike and one for city bombard.
Or
If there is no valid defende(max air combat dmg reached),
Just bombard city defense according to the rules of regular bombard.
I just dont want there to be 2 missions that allow both, i.e. Regular bombard.
Though i do want to enact ranged bombard if ciry defence,, again same as air bombard.

Anyway,
I have set that, if max air combat reached to all and each unit on the plot,
Tgere wont be an option to waste a strike that consumes movment, i. g. Damage of 0% to unit that were attacked.
 
The code is just changed from if (pDefender != NULL) in the strikeback segment. Donno if you guys (F1Pro) made changes.

I remember why I did the Bombard defenses on the rangestrike. It was because I wanted ranged>1 and was too lazy to edit the bombard method ;)
It would make sense to change it though, since it never uses the if defense > 0 then reduce the damage by %citydefense.
 
Ill share the code i did.
Im just trying now to handle the
Bombard issue.
My opinion keeps shifting:

1.Ranged strike with reduce city defence:

A. First reduce city defence than units.
B. Both at the same time

2. Ranged stike separated:
Only strike units
Regular bombard (no range, maybe edit)

Im playing with the code.
Have no idea how the ai will handle it.
 
Hi Vincentz!

Just wanted to come back and give honour where honour was due. Once again I'm bitten by the Civ bug and I am uninspired by the newer versions... yours was the best mod I ever had for Civ IV; god only knows if it will even work on my stupid new computer, but Imma give it a shot and see. Glad to see you still here and working hard - salutes from Canada!
 
So i revisited the mod after a year and i´m currently very engaged in a match. However I´m getting a CTD once I finish the national library project, I suppose due to getting some techs. Anyway to fix it?
 

Attachments

Back
Top Bottom