Announcement

Collapse
No announcement yet.

Popular Uprisings and other Triggers

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Popular Uprisings and other Triggers

    This is an idea for a trigger I am developing. The motivation is to generate internal strife within an empire that might contribute to its eventual downfall.

    It revolves around the idea that the player or AI is the continually re-incarnated leader of your nation... but you are not the whole nation. The Citizens of your nation have opinions about how you do things.

    Some events are likely to make your people call out for blood:
    city.captured when its your city by another civ
    agreement.broken when you are the victim
    special.attacked when you are the victim
    special.terrorism when you are the victim
    special.citizenenslaved when you are the victim
    special.settlerenslaved when you are the victim
    special.victoryenslavement when you are the victim
    special.piracy when you are the victim
    special.pillage when you are the victim

    Some things you do will result in protests:
    city.captured by barbarians
    city.captured from a peaceful civ.
    player.pollution from you
    unit.dead when it is a Nuke that you used
    unit.deadnofuel because you screwed up
    unit.deadnosupport because you screwed up
    agreement.broken when you broke it
    special.terrorism when you are the attacker
    special.attacked when you are the attacker
    special.terrorism when you are the attacker
    special.citizenenslaved when you are the attacker
    special.settlerenslaved when you are the attacker
    special.victoryenslavement when you are the attacker
    special.piracy when you are the attacker
    special.pillage when you are the attacker


    Now so long as you are responding to an attack ie your people are already calling out for blood... then you could go trample all over that offensive civ and no one would get upset. However if you are the instigator you should not go to far to fast or you own people might oust you.

    Implementing this is easy enough. Each player will have a rating and a delta.
    Every turn the rating and delta will both decay towards 0 and the delta will also be added to the rating.

    Events as described above will alter the current delta value by some fixed amount. This effectively gives the rope with which to hang oneself.

    Lets say your unrest level is 0.
    And you co capture 4 enemy cities in one turn. This increases your delta to say 40.
    Next turn your unrest rating=0+40-1=39 and the delta=40-1=39.
    Next turn unrest rating=39+39-1=77 and the delta=39-1=38..
    Next turn unrest rating=77+38-1=114 and the delta=38-1=37..
    etc etc etc...

    Interpretation: Your people considered your war against the other civ to be unjustified. They had done nothing to you. If you had taken maybe one city they may have been ok with that and settled down eventually but you captured 4, you're a frickin despot and they're freakin on you! You better make restitution somehow or they're gonna defect or something.

    The amends part I'm working on.

    Anyway those are my thoughts on this and they are developing.

  • #2
    The overall idea seems sound to me. Be sure to throw in government effects..obviously under fascism you should be able to act nastier than under democracy before unrest happens.

    Comment


    • #3
      Yes I've been considering that too.

      I don't want to unbalance the governements though so such things take a great deal of care and consideration. I've had thoughts like...
      Ok a fascist gov may be able to take a city without upsetting their people as much as they would in a democracy. However all govs call out for a similarly larger amount of blood when they do so.

      Meaning that while a democracy could not fight an agressive war against anyone it would be particularly good at retribution. "You take one of mine I'll take two of yours".

      There's nothing quite like a democracy incited to war.

      This is a significant trigger and must not be taken lightly. It will profoundly alter the game.

      Gedrin

      Comment


      • #4
        Hey sounds like a great idea!!!!

        But, one problem I can think of immediately is that you can't save values of variables without ctp crashing.

        I'll explain, if you had a trigger to increment the value of "x" by 1 each turn, it would do it, but when you save the game and then later try to load that game it will either crash when loading or crash on the next game turn.

        I just wanted to say that so you don't waste your time if that was the way you were planning to program the trigger. There may be another way around that, I don't know what exactly you had in mind but I just thought I'd let you know. There's gotta be a work around though.

        But man, if you can do all that you are talking about that is really !!!!!!

        ------------------
        Gemini
        [This message has been edited by gemini (edited September 29, 2000).]

        Comment


        • #5
          Gemini is probably right, both he and I experienced problems with that in the past. This may also be causing the mysterious MedMod crashes, like I said in a post on the CtP General Forum (along with a way to test this).

          But the idea's sound themselves sound very cool. I think the best (and probably only ) solution however might be to wait for CtPII, SLIC will be much more powerfull and the variable thing may well have been fixed there.
          Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

          Comment


          • #6
            Hmmm.... I had not thought of that... or realized it really...
            This might work though:
            INT Preference(prefname)
            INT SetPreference(prefname, value)

            'Course if you are playing multiple games you will need to swap out userprefs.txt (is that the file name? Can't recall)
            And this does rely on the idea that the prefs file is updated or at least can be updated when a value is changed... but I'm unsure of that one either.

            Anyone know for sure?

            Gedrin

            Comment


            • #7
              Hi Gedrin,

              Your idea sounds very good. However, I have only one question. Will the AI be aware of these things like the human is? If the AI is not, then this whole setup is a recipe for the AIs to self destruct every time and very quickly, unless you apply these rules only to the human player. However, if you only apply these rules to the human player, you are giving the AIs a huge advantage, though that may be what they need to be competetive.

              Timothy Pintello

              Comment


              • #8
                Yes, I've been concerned about that too.

                My approach is to contrive the rules to benifit strategies that the AI already engages in. I do not see AI's going on the decidedly Human 'Holy Jihad' and totally destroy a civ, always refusing to accept peace. I mean that's what I do. I *never* start wars but once one starts it usually ends with a message something like...
                The has been completely destroyed...


                My desire is to make it harder for human players to do things that human players do. Make them play more moderately, a little more like an AI.

                Of course this all may be a moot point if I can't persist the values over a restart.

                Gedrin

                Comment


                • #9
                  No, storing it in profile.txt won't work either, simply because you can't add your own fields to it. I've tried but it doesn't work.
                  Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

                  Comment


                  • #10
                    Oh Pooh.

                    Ok how about this.
                    Regard for players.
                    IE the
                    ForceRegard(ofPlayer, forPlayer, toRegard): Force the regard ofPlayer forPlayer toRegard.
                    INT RegardLevel(player1, player2): Return player 1's regard toward player 2.

                    One could imagine these values are stored in an array. I wonder if we can store values in the player (n,n) element. Anyone know? Anyone want to same me the trouble of checking? Anyone know legal ranges of this value?

                    If it can be set then two values can be stored in it easily by either using the decimal digit columns or actually spliting the values into bits... say 5 most sig for a rating and 3 least sig for a delta.

                    Now this will take some testing.


                    Gedrin

                    Comment


                    • #11
                      Arrgg...

                      Those with a keen eye will notice I have an infinite loop in the trigger above...

                      The terrorist is currently being tested so I make no garuntees about it yet. :P
                      the while loop should be:


                      if (g.player == 0) {
                      totalScore = 0;
                      index = 1;
                      while (index < numberOfPlayers) {
                      SetPlayer(1,index);
                      totalScore = totalScore + player.1.score;
                      index = index + 1;
                      }
                      } else {


                      I forgot that index = index + 1;
                      Although I have not hit an infinite loop yet so I think I must have changed it already at home :O

                      Gedrin

                      Comment


                      • #12
                        quote:

                        Originally posted by Gedrin on 10-02-2000 11:58 AM
                        Oh Pooh.

                        Ok how about this.
                        Regard for players.
                        IE the
                        ForceRegard(ofPlayer, forPlayer, toRegard): Force the regard ofPlayer forPlayer toRegard.
                        INT RegardLevel(player1, player2): Return player 1's regard toward player 2.

                        One could imagine these values are stored in an array. I wonder if we can store values in the player (n,n) element. Anyone know? Anyone want to same me the trouble of checking? Anyone know legal ranges of this value?

                        If it can be set then two values can be stored in it easily by either using the decimal digit columns or actually spliting the values into bits... say 5 most sig for a rating and 3 least sig for a delta.

                        Now this will take some testing.


                        Gedrin




                        Christ, that's so desperate you're better of waiting for CtPII But it *could* indeed work.

                        I'm not sure if there are legal ranges for the regard values (other then that they have to be integers of course) and I wouldn't know where to look for them. I guess trial and error is the way to go.

                        Damn, for the first time since I bought CtP I don't have it installed and I immediately regret it And it doesn't look like I'll be getting a lot of free disk-space anytime soon
                        Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

                        Comment


                        • #13
                          As promised some of the other triggers I experiment with:


                          //Setup
                          trigger 'Setup' when ((g.player == 0) && (g.year == 0)) {
                          // This is the value from userprofile.txt that details the number of players that STARTED the game.
                          // This may of course be very different from the number currently in the game.
                          numberOfPlayers = Preference("NumPlayers");
                          }

                          messagebox 'PopFlees' {
                          // POP_FLEES must be defined in info_str.txt and reads like:
                          // POP_FLEES "Refugees from [city.1.name] flee in terror."
                          Text(ID_POP_FLEES);
                          MessageType("WARNING");
                          }

                          trigger 'Refugees' when (city.captured) {
                          // This value will rounded down.
                          popCount = city.1.population / 2;
                          cityCount = Cities(player.2);
                          // Skip the last city in a civ. They have nowhere to go.
                          // Optionaly we could find a Random civ that is still alive and let them flee there.
                          if (cityCount > 0) {
                          AddPops(city.1, -popCount);
                          Message (player.1, 'PopFlees');
                          Message (player.2, 'PopFlees');
                          index = 0;
                          while (index < popCount) {
                          destCity = Random(Cities(player.2));
                          SetCityByIndex(2,player.2,destCity);
                          AddPops(city.2, 1);
                          index = index + 1;
                          }
                          }
                          }

                          messagebox 'PopEmmigrates' {
                          // POP_EMMIGRATES must be defined in info_str.txt and reads like:
                          // POP_EMMIGRATES "Your authority is questioned in [city.2.name]. Citizens have Emmigrated to [city.3.name]."
                          Text(ID_POP_EMMIGRATES);
                          MessageType("INCITE");
                          }

                          messagebox 'PopImmigrates' {
                          // POP_IMMIGRATES must be defined in info_str.txt and reads like:
                          // POP_IMMIGRATES "Political refugees arrive from [city.2.name] in [city.3.name].
                          Text(ID_POP_IMMIGRATES);
                          MessageType("INCITE");
                          }

                          // PopMigration and B-Tax merged for speed.
                          trigger 'AvePopBasedEffects' when ((g.player) && (g.year)) {
                          cityCount = Cities(g.player);
                          totalPop = 0;
                          smallestPop = 100;
                          index = 0;
                          // find the total population and smallest city
                          while (index < cityCount) {
                          SetCityByIndex(1, g.player, index);
                          totalPop = totalPop + city.1.population;
                          // Remember which is the smallest-newest city for PopMigration
                          if (city.1.population <= smallestPop) {
                          SetCityByIndex(2,g.player,index);
                          smallestPop = city.2.population;
                          }
                          index = index + 1;
                          }

                          // apply the BureaucracyTaxes
                          surtax = (2*totalPop - cityCount * cityCount) * (600 - g.year) / 200;
                          AddGold(g.player,surtax);

                          // Migration becomes more likey as time goes on and while ave pops remain low.
                          // if ((g.year/30) > (Random(20) + avePop))
                          if ((cityCount*g.year) > (30*(Random(20)*cityCount + totalPop))) {
                          recipientPlayer = 0;
                          cityCount = 1000;
                          // find the civ with fewest cities
                          index = 1;
                          // Exclude player = 0 so the Barbarians do not get them at all.
                          while (index < numberOfPlayers) {
                          if ((Cities(index) > 0) && (Cities(index) < cityCount)) {
                          cityCount = Cities(index);
                          recipientPlayer = index;
                          }
                          index = index + 1;
                          }
                          // if it is not me then move 1 pop... yes this does mean the player with
                          // the fewest cities may ICS with impunity, to catch up of course.
                          if (recipientPlayer != g.player) {
                          // This actually produces a number from [0,cityCount) ie not inclusive!!!
                          index = Random (cityCount);
                          SetCityByIndex(3,recipientPlayer,index);
                          Message (g.player,'PopEmmigrates' );
                          Message (recipientPlayer,'PopImmigrates' );
                          AddPops(city.2, -1);
                          AddPops(city.3, 1);
                          }
                          }
                          }

                          Gedrin

                          Comment


                          • #14
                            I forgot one:
                            This also requires the setup trigger above to set numberOfPlayers


                            messagebox 'PopTerrorized' {
                            // POP_TERRORIZED defined in info_str.txt reads like:
                            // POP_TERRORIZED "Foreign backed terrorists strike in [city.1.name]. Casualties are high."
                            Text(ID_POP_TERRORIZED);
                            MessageType("WARNING");
                            }

                            trigger 'AveScoreBasedEffects' when ((g.player) && (g.year)) {
                            // Player = 0 is the Barbarian who does not suffer from terrorist...
                            // but we still need the total score since ave = total/number
                            if (g.player == 0) {
                            totalScore = 0;
                            index = 1;
                            while (index < numberOfPlayers) {
                            SetPlayer(1,index);
                            totalScore = totalScore + player.1.score;
                            }
                            } else {
                            cityCount = Cities (g.player);
                            if (cityCount > 0) {
                            SetPlayer(1,g.player);
                            // This equates to [-2,0] + (player.1.score - aveScore)/aveScore
                            // I multiplied by numberOfPlayers/numberOfPlayers = 1 to clear some divisions
                            strikes = Random(3) - 2 + (player.1.score * numberOfPlayers - totalScore)/totalScore;
                            while (strikes > 0) {
                            destCity = Random (cityCount);
                            SetCityByIndex(1,g.player,destCity);
                            AddPops(city.1, -1);
                            Message(g.player, 'PopTerrorized');
                            strikes = strikes - 1;
                            }
                            }
                            }
                            }


                            Gedrin

                            Comment


                            • #15
                              Yes, I have tested to see what it returns with the regardlevel function. If I remember correctly it returns an integer ranging from 1 to 5 (or 0 to 5 can't remember), anyway 1 is low regard and 5 is high.

                              Btw, I read your other post about storing variables and I read Locutus's response. I can't explain why you have no problems loading your games when you use your trigger. I would be interested in knowing if your variables are retained correctly after loading. Let me know. Thxs.

                              Anyway, Ctp does remember which triggers have been disabled. And I haven't run into any problems disabling and enabling triggers over and over when loading save games. I did something similar for my on map date display. Any way, maybe you could set ranges for certain triggers and disable other triggers that don't apply.

                              Eg.
                              Code:
                              trigger 'ged' when (g.player){
                              x = 40;
                              }
                              
                              trigger 'gad' when (g.player){
                              x = 50;
                              }
                              
                              trigger 'god' when (g.player){
                              x = 60;
                              }
                              
                              trigger 'gcd' when (g.player){
                              x = 70;
                              }
                              
                              trigger 'code' when (g.player){
                              if(player.cities < 2){
                              disabletrigger('gcd');
                              disabletrigger('ged');
                              disabletrigger('gad');
                              
                              }
                              
                              if(player.cities > 1 | | player.cities < 5){
                              disabletrigger('god');
                              disabletrigger('ged');
                              disabletrigger('gad');
                              }
                              
                              if(player.cities > 4){
                              disabletrigger('gad');
                              disabletrigger('god');
                              disabletrigger('gcd');
                              }
                              }
                              
                              trigger 'whatyouwanttorun' (g.player){
                              if(x == 60){
                              //run the code
                              }
                              
                              if(x == 
                              
                              sorry not worth it for me to go on and on but thats it
                              }
                              I know the code above doesn't make much sense but it's the idea that might be useful.
                              I thought I might throw it at you.

                              Looking back at your post about the regardlevel function, if I am understanding correctly, you want to store values in the element for the regardlevel function??? Like regardlevel(12,12);

                              If that's what you want to do I know it won't work. Only the built in player variables work in there.

                              ------------------
                              Gemini
                              [This message has been edited by gemini (edited October 03, 2000).]

                              Comment

                              Working...
                              X