adapt a script

Hi, I need help, basically I'm trying to make a promotion for a unit, which when it enters a city of another faction, unhappy for 15 turns, my doubts are how to make it work only in cities of other factions civilization and make it temporary, I gave it a first try. Thanks.
This is how it works, but only for my city
 

Attachments

  • 1.png
    1.png
    17.8 KB · Views: 6
Last edited:
(Based on a few notes I took after having a look at your earlier attached image.) Looks like HappinessTimer is based on ...
XML:
<Define>
	<DefineName>TEMP_HAPPY</DefineName>
	<iDefineIntVal>1</iDefineIntVal>
</Define>
... in GlobalDefines, so it'll always have a positive effect. Unless you change it to -1 in XML, but that may break random events that also use HappinessTimer.

Looking at CvCity::unhappyLevel (perhaps see also the next function, CvCity::happyLevel, for the DLL's use of TEMP_HAPPY), I see the following temporary sources of unhappiness: Hurry, Conscript, DefyResolution, Espionage. Probably the explanation texts (e.g. "cannot forget your cruel oppression") won't really fit your purposes. And changing the timers will prolong existing unhappiness effects, e.g. when the city has recently used Slavery.

Your (initial) idea of combining ExtraHappiness with an unrelated timer seemed promising. Set negative ExtraHappiness, set the timer, check the timer every turn and undo the ExtraHappiness change when it has expired. It's just that all those happiness timers have their own impact on happiness. Implementing your own timer in Python would be complicated because the state of the timer needs to be stored in savegames. It should be doable through CyCity.setScriptData/ getScriptData, but I've no experience with that.

Maybe if you'd disable the random events that use HappinessTimer? Apparently, having searched EntryPoints\CvRandomEventInterface.py, those events are WeddingFeud and GreatBeast. Then you'd be free to change TEMP_HAPPY to -1 and wouldn't need ExtraHappiness. And TXT_KEY_HAPPY_TEMP ("Past events went well!") could also be changed to match your purposes.

As for city ownership – shouldn't it suffice to just negate the condition that you have, i.e. to check for inequality (!=)? Or if you want the check to be at the level of teams, then getTeam instead of getOwner should do the job. Or maybe you're saying that changeExtraHappiness somehow has no effect on non-human cities? I don't think that should be the case.
 
I hadn't thought about the solution to the inequality :(
could it go like this? we could make that after 5 or 10 turns the unit dies, but I don't know how to write it, it could be a good idea, and it would make the A.I. easier. Thanks for your availability as always
 

Attachments

  • 1.png
    1.png
    25.4 KB · Views: 7
Comparing a team ID with a player ID (owner) is not good. Should then also be pUnit.getTeam(). And !=, right? And, if you also check whether the unit has left, the team/ player ID check for that should be the same as for the arrival check.

I don't think a timer for destroying the unit will be any easier than a timer for the ExtraHappiness itself. It could easily be destroyed with a per-turn probability. Not sure how you'd get the AI to keep the unit in place. Even if HappinessTimer is used (which wouldn't require the unit to stay), there's a question of how to get the AI to send the unit to foreign cities. Maybe you already have a plan for that? This whole idea seems pretty similar to the Foment Unhappiness espionage mission, but I guess that's no help if you want to tie the effect to a promotion that any unit could receive.

For a timer implemented in Python, you'd need to store the remaining turns of any active timers along with the IDs of the cities that the timers refer to; and you'd need to turn that data into a script data string and send that to the DLL through CyCity.setScriptData (just) before the game gets saved; and restore the data from the script data string to be obtained from the DLL after loading a savegame. For some of these steps, it's clear when they should happen (set the timer on onUnitMove, decrease it at the start of a player turn), but, for others, I'm not sure. There's also a class PyCity (as opposed to CyCity) that could perhaps store the timer values; don't know if that's how persistent city data should be implemented in Python. In other words, I'm no real help for this approach. This guide seems to deal with this very subject.
 
Comparing a team ID with a player ID (owner) is not good. Should then also be pUnit.getTeam(). And !=, right? And, if you also check whether the unit has left, the team/ player ID check for that should be the same as for the arrival check.

I don't think a timer for destroying the unit will be any easier than a timer for the ExtraHappiness itself. It could easily be destroyed with a per-turn probability. Not sure how you'd get the AI to keep the unit in place. Even if HappinessTimer is used (which wouldn't require the unit to stay), there's a question of how to get the AI to send the unit to foreign cities. Maybe you already have a plan for that? This whole idea seems pretty similar to the Foment Unhappiness espionage mission, but I guess that's no help if you want to tie the effect to a promotion that any unit could receive.

For a timer implemented in Python, you'd need to store the remaining turns of any active timers along with the IDs of the cities that the timers refer to; and you'd need to turn that data into a script data string and send that to the DLL through CyCity.setScriptData (just) before the game gets saved; and restore the data from the script data string to be obtained from the DLL after loading a savegame. For some of these steps, it's clear when they should happen (set the timer on onUnitMove, decrease it at the start of a player turn), but, for others, I'm not sure. There's also a class PyCity (as opposed to CyCity) that could perhaps store the timer values; don't know if that's how persistent city data should be implemented in Python. In other words, I'm no real help for this approach. This guide seems to deal with this very subject.
for the A.I. Since it's a Great spy unit type,
cted linked to a particular civic, which enhances espionage, so I created a unit by copying the great spy "suspected corrispondent", but which only gives a bonus of 10%, which however should also give this penalty
, so it should do this, I'm thinking that maybe it's better to have it force the construction of a building, and then create an event that triggers for that building for a certain number of turns, which do you think? could it work?I have the impression that I will stay on Civ 4 for many more years, because I think I won't like Civ7 :)
 

Attachments

  • 1.png
    1.png
    1.1 MB · Views: 10
  • 1.png
    1.png
    872.2 KB · Views: 6
Last edited:
I tried to do it by adding a building, but it doesn't work. here is the script (screen 1)

I tried this it doesn't give me errors but it doesn't create the building (screen 2)
 

Attachments

  • 1.jpg
    1.jpg
    41.9 KB · Views: 6
  • 1.jpg
    1.jpg
    37.8 KB · Views: 4
Last edited:
Is the promotion only given to a particular unit? Would it be easier, then, to just test for the unit type in Python and to get rid of the promotion? Or maybe the unit could have the Foment Unhappiness mission. Well, maybe best to leave the context to you and for me to focus on the programming. I don't know what exactly random events can and can't do. Apparently, there's the HappinessTimer, which, I believe only grants (positive) happiness. Also, if that's what the event will do, then it would seem simpler to set the HappinessTimer directly in onUnitMove rather than taking a detour via a building and random event. The Cv/CyCity function for adding a building is setNumRealBuilding. The first parameter is the building ID (building type - as in your 2nd attempt), the second either 0 (to remove the building) or 1 (to add it).
 
in this way?

if it works adding a building is perfect :)
p.s. maybe is ), 1)secondo screen. give me error, not defined Building
 

Attachments

  • 1.jpg
    1.jpg
    39.2 KB · Views: 5
  • 1.png
    1.png
    19.3 KB · Views: 6
Last edited:
No, like you already had it (in your 2nd screenshot), just plus the quotation marks. The string is the sole parameter for getInfoTypeForString. The result of that is the building ID. And that ID is the first of two parameters of setNumRealBuilding.
 
No, like you already had it (in your 2nd screenshot), just plus the quotation marks. The string is the sole parameter for getInfoTypeForString. The result of that is the building ID. And that ID is the first of two parameters of setNumRealBuilding.
pCity.setNumRealBuilding(gc.getInfoTypeForString('BUILDING_SPY_SCHOOL'), 1)
work :) thx so much

this was the fault of the wasted time :) without mark
 

Attachments

  • 2.jpg
    2.jpg
    12.1 KB · Views: 3
Last edited:
Hi, sorry again, I wanted to add another option to the script by adding this one, but it doesn't work,

I don't know how to say that the Team is practically that of the city
I'll attach the screen. thank you always
 

Attachments

  • 1.jpg
    1.jpg
    11.5 KB · Views: 4
  • 3.jpg
    3.jpg
    38.3 KB · Views: 3
Last edited:
It looks like it should work ... Oh, the callee is wrong; setEspionagePoints... is not a CvUnit function; it's a CvTeam function. So, instead of pUnit, it needs to be: gc.getTeam(pUnit.getTeam())
The first parameter of your function call could also be simplified to just pPlot.getTeam() or pCity.getTeam(). Most entities that have an owner have both a getOwner (returning a player ID) and a getTeam function (returning a team ID). Obtaining the player or team object (usually in order to call one of its functions) gets more complicated, involving the gc.getPlayer/getTeam functions.
 
Hm, I guess you really want to subtract 100 points from the city owner. So maybe it should be:
gc.getTeam(pCity.getTeam()).changeEspionagePointsAgainstTeam(pUnit.getTeam(), -100)
 
Hm, credo che tu voglia davvero sottrarre 100 punti al proprietario della città. Quindi forse dovrebbe essere:
gc.getTeam(pCity.getTeam()).changeEspionagePointsAgainstTeam(pUnit.getTeam(), -100)
yes. because I noticed that the A.I. if I use great spy as a vbase, it never uses it, while if I use great merchant as the basis for my new unit, it uses it. Thanks as always, I'll try it now.


edit
I add the function again and I can only write the new function, below a pCity.setNumRealBuilding(gc.getTeam('BUILDING_SPY_SCHOOL'), 1), like second screen
 

Attachments

  • 1.jpg
    1.jpg
    66.9 KB · Views: 4
  • 1.jpg
    1.jpg
    45.5 KB · Views: 6
Last edited:
Sure, the 2nd screenshot should be equivalent to the first; no need to repeat all the checks if they're the same for both events. (Off to sleep again.)
 
Hi, I'm trying to make a script that declares war on a civilization as soon as it establishes a specific religion, I tried with my little knowledge on the subject to give it a try. I hope it goes well. Thanks for your help.
 

Attachments

  • 123.jpg
    123.jpg
    48.9 KB · Views: 5
Back
Top Bottom