Announcement

Collapse
No announcement yet.

Popular Uprisings and other Triggers

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

  • #16
    That sounds like a good alternative, Gemini. Personally I'd probably go with that rather then with the regard thing, but that's just me...

    quote:

    Originally posted by gemini on 10-03-2000 02:26 AM
    Only the built in player variables work in there.



    True, but you can say something like this:

    player.1 = 12;
    player.2 = 12;
    RegardLevel(player.1, player.2);

    I used this to create barbarian units for flat-map support so I know for sure that this will work. Only you're probably limited to numbers between 0 and 32 and IIRC all non-existing players are automaticly barbarians. So if you have 8 players in the game, player 0 and players 9 and higher are all really the same player (though I'm not entirely sure about this).
    Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

    Comment


    • #17
      Locutus:
      Have you been able to set the player context with:
      player.1 = x;
      I thought it crapped out when you tried to write to built in variables. That's what the VOID SetPlayer(index, player) function is for.

      Doesn't change the accuracy of your statement though. That is what I had in mind for setting regard.

      I imagine since the regard goes from 0 to 5 (vs 1 to 5) and these are War; Angry; Unhappy; Neutral; Happy; Love.
      This is a shame since I doubt the function would allow larger values.

      However, having said that and having read the thread Locutus pointed me too I do not think it matters.

      As you probably know SLIC is not using a true random number generator... or at least I don't think it does. It uses a pseudoRandom function. This means that the nth random number will be x and if you back up to some prior condition it will be x again. I have repeatedly saved games, run a turn, got a disseminated tech, reloaded a game and again got a disseminated tech. In addition I have never failed to get this result. This makes me very confident, although not positive, that the values used in my disseminate trigger are preserved over restarts.
      IE:numberOfPlayers and numberWith*some_advance*

      I believe quite strongly that the entire SLIC stack would be saved on a savegame.

      I do not know why the triggers described [in the thread Locutus pointed to me] crashed on a restart. I suspect actually that some small error was made in typing it in.

      Would:
      trigger 'move' when (IsHumanPlayer(g.player)){
      even load?

      trigger 'move' when (IsHumanPlayer(g.player) == 1){
      might.
      Having noted that and assuming that this was the case then I also have concerns over placing IsHumanPlayer in the trigger conditions. There are warnings about this sort of thing in the SLIC guide.

      The reason I suspect this is that (IsHumanPlayer(g.player) == 1) does not provide enough information to determine if it is true or not. You also need to know if g.player is human.

      On the other hand something like g.player == 1 does provide enough information since g.player is an integer already. You guys follow me?

      I suspect that to be the cause of the crash but would need to know a good deal more about the guts of SLIC to answer it.

      Having read over point 2) in the at thread also I think this is the sort of thing you need.

      TypeLocation locationvar;

      VOID MakeLocation(locationvar, x, y, z)
      Set locationvar to (x,y,z)

      VOID SetLocation(index, locationvar)
      Set location.index to locationvar.

      VOID ExtractLocation(location, locationvar)
      Get a location from built in variable and put it in locationvar.

      These can be used in combination to handle any function arguments depending on if they expect a user defined TypeLocation locationvar; or a built variable in the location container: SetLocation(3, locationvar) and then use location.3 in a function... or gain access to any of the fields on location [which unfortunately are not detailed in the SLIC docs]; or even just a index into the current location context.

      Gedrin


      And on another note: My Terrorist Trigger 'fully' tested for functionality. I have no idea how well it balances things but it should certainly hamper the runaway civ... Human or AI.



      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 'AveScoreEff' when ((g.player) && (g.year)) {
      // Player = 0 is the Barbarian who does not suffer from terrorist attacks
      // but we still need the total score since ave = total/number
      if (g.player == 0) {
      totalScore = 0;
      numberPlayersLeft = 1;
      index = 1;
      while (index < Preference("NumPlayers")) {
      if (IsPlayerAlive(index) == 1) {
      SetPlayer(1,index);
      totalScore = totalScore + player.1.score;
      numberPlayersLeft = numberPlayersLeft + 1;
      }
      index = index + 1;
      }
      } else {
      cityCount = Cities (g.player);
      // Note that CityCount > 0 is not the same as IsPlayerAlive. Consider turn 0.
      if (cityCount > 0) {
      SetPlayer(1,g.player);
      // The following = Random(3) - 2 - (player.1.score - average)/average
      // where average = totalScore/numberPlayerLeft
      strikes = Random(3) - 3 + (player.1.score * numberPlayersLeft / totalScore);
      // The chances that a terrorist strike kills a civ's last city is small but not nil
      while ((strikes > 0) && (cityCount > 0)) {
      destCity = Random (cityCount);
      SetCityByIndex(1,g.player,destCity);
      // Always message BEFORE reducing pop since it might destroy the city
      Message(g.player, 'PopTerrorized');
      AddPops(city.1, -1);
      cityCount = Cities (g.player);
      strikes = strikes - 1;
      }
      }
      }
      }


      Gedrin

      Comment


      • #18
        Gedrin,

        quote:


        Locutus:
        Have you been able to set the player context with:
        player.1 = x;
        I thought it crapped out when you tried to write to built in variables. That's what the VOID SetPlayer(index, player) function is for.
        Doesn't change the accuracy of your statement though. That is what I had in mind for setting regard.



        Sorry, I made a minor mistake, it should be:
        x = 12;
        y = 12;
        RegardLevel(x, y);

        You can't set built-in variables (directly) but you *can* use user-defined variables whenever you would normally have used built-in ones. I don't know what I was thinking when I wrote that down

        quote:


        I imagine since the regard goes from 0 to 5 (vs 1 to 5) and these are War; Angry; Unhappy; Neutral; Happy; Love.
        This is a shame since I doubt the function would allow larger values.



        Hmm, you're probably right. I think I got confused with something else when I said there probably was no limit.

        quote:


        However, having said that and having read the thread Locutus pointed me too I do not think it matters.

        As you probably know SLIC is not using a true random number generator... or at least I don't think it does. It uses a pseudoRandom function. This means that the nth random number will be x and if you back up to some prior condition it will be x again. I have repeatedly saved games, run a turn, got a disseminated tech, reloaded a game and again got a disseminated tech. In addition I have never failed to get this result. This makes me very confident, although not positive, that the values used in my disseminate trigger are preserved over restarts.
        IE:numberOfPlayers and numberWith*some_advance*



        Yeah, I noticed that the Random function was only pseudo-random as well but didn't draw any conclusions from it. You have a good point there. (Where were you six months ago? )

        quote:


        I believe quite strongly that the entire SLIC stack would be saved on a savegame.

        I do not know why the triggers described [in the thread Locutus pointed to me] crashed on a restart. I suspect actually that some small error was made in typing it in.



        It could well be, I must say I'm doubting our theory more and more as well. Oh well, it was nice while it lasted

        quote:


        Would:
        trigger 'move' when (IsHumanPlayer(g.player)){
        even load?

        trigger 'move' when (IsHumanPlayer(g.player) == 1){
        might.
        Having noted that and assuming that this was the case then I also have concerns over placing IsHumanPlayer in the trigger conditions. There are warnings about this sort of thing in the SLIC guide.

        The reason I suspect this is that (IsHumanPlayer(g.player) == 1) does not provide enough information to determine if it is true or not. You also need to know if g.player is human.

        On the other hand something like g.player == 1 does provide enough information since g.player is an integer already. You guys follow me?

        I suspect that to be the cause of the crash but would need to know a good deal more about the guts of SLIC to answer it.



        I think the "trigger 'move' when (IsHumanPlayer(g.player)) {" should work.
        IsHumanPlayer(g.player) will return either true (but since there is no boolean datatype it will return 1) or false (or 0), so "(IsHumanPlayer(g.player))" and "(IsHumanPlayer(g.player) == 1)" do exactly the same, the logical expression "(1)" is the same as the expression "(1 == 1)" (the last one will evaluate to "(1)" anyway). I hope you can follow this.

        Also, I'm pretty confident that I've used it before with succes. In fact, even in Activision's standard script.slc file it's used as trigger condition several times (though always in combination with other conditions, so that doesn't say everything).

        I read through the entire SLIC guide but couldn't find the warnings you are referring to.

        You say that you don't have enough information and that you need to know if g.player is human, but isn't that exactly what IsHumanPlayer does? I agree though that "g.player == 1" or even better, just "g.player" and check if the player is human later with an if-statement, is safer but using IsHumanPlayer as trigger condition should work as well.

        Anyway, most of SLIC 1 looks like it was just hacked together anyway and not at all finished, so I expect and hope that all will be better in SLIC 2.

        quote:


        Having read over point 2) in the at thread also I think this is the sort of thing you need.

        TypeLocation locationvar;

        VOID MakeLocation(locationvar, x, y, z)
        Set locationvar to (x,y,z)

        VOID SetLocation(index, locationvar)
        Set location.index to locationvar.

        VOID ExtractLocation(location, locationvar)
        Get a location from built in variable and put it in locationvar.

        These can be used in combination to handle any function arguments depending on if they expect a user defined TypeLocation locationvar; or a built variable in the location container: SetLocation(3, locationvar) and then use location.3 in a function... or gain access to any of the fields on location [which unfortunately are not detailed in the SLIC docs]; or even just a index into the current location context.

        Gedrin



        I'm not sure what you're trying to tell but if you'd like to know how I eventually implemented the MakeLocation thing, I suggest you have a look at the flatmap version of MedMod 4

        Locutus

        BTW, your SLIC triggers look very cool, if I ever reinstall CtPI again I'll try them out
        [This message has been edited by Locutus (edited October 03, 2000).]
        Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

        Comment


        • #19
          Locutus

          Six months ago I was digging a project out that had been assulted by programmers who knew enough about OO to be very very dangerous.

          I think you are right about the evaluation of integers as booleans. 1 is true and 0 is not. Been working too long in a strongly typed language I think.

          I withdraw all suspicions about IsHumanPlayer and SLIC crashes... I now havn't a clue... helpful arn't I

          The warning paragraph is on: http://apolyton.net/ctp/modification/slicbuiltin.shtml
          Each trigger object you create is only triggered for one type of event, even though it may contain more
          than one variable that can be used as a trigger event! See Trigger Priorities for a discussion of how to
          determine which events will cause your trigger to be run. A good way to be safe is to just put as little logic
          in the when(...) condition as possible, and instead move everything else to an if(...) {} inside the trigger.

          And you know you want it re-install CTP... it's not CTPII is out yet.

          Oh and yeah Flat Map... just looked over. Seems you knew what I was talking about.

          Gedrin

          Comment


          • #20
            I don't get to the creation forum much any more, and so I have just read the entire thread here for the first time. To summarize: Does anyone have any ideas about the Med mod crashes?

            Also, Gedrin, I was getting you mixed up with Gemini regarding the Partisan trigger.
            Gemini, do you have such a trigger, ala civ2's, for your WWII mod?

            You three, Locutus, Gemini and Gedrin, need to get together and list all the triggers that you have developed, either in the same or individual threads. No need for the code, just a brief description of the triggers. I think you may be surprised at what the others have done. Also, you may want to list ideas for triggers that you have, and triggers that you could not get to work, with the code included.
            I am mainly looking ahead to CtP2 and its improved slic2 as far as using these lists and ideas. The game will be out before you know it, and it doesn't hurt to start kicking ideas around and comparing notes now. This thread is evidence that you are already doing that some, but putting things out in a detailed and standardized way would be beneficial to everyone, imo.

            Comment


            • #21
              Gedrin,

              quote:


              The warning paragraph is on: http://apolyton.net/ctp/modification/slicbuiltin.shtml
              Each trigger object you create is only triggered for one type of event, even though it may contain more
              than one variable that can be used as a trigger event! See Trigger Priorities for a discussion of how to
              determine which events will cause your trigger to be run. A good way to be safe is to just put as little logic
              in the when(...) condition as possible, and instead move everything else to an if(...) {} inside the trigger.



              I saw that paragraph but I didn't see how applying functions in trigger conditions has anything to do with it. Now you mention it and I rethink it, I know what you mean, but I still don't think it should be a problem (not in this case anyway).

              quote:


              And you know you want it re-install CTP... it's not CTPII is out yet.

              Oh and yeah Flat Map... just looked over. Seems you knew what I was talking about.

              Gedrin


              Yeah, I know I want to reinstall it, but if I can is a different matter altogether
              That probably won't be the case before CtPII comes out so I decided to just give CtP up altogether, but I just couldn't resist to at least keep posting here

              Wes,

              As far as the crashes go: no, we haven't got a frinnin' clue

              Partisan trigger? Isn't that from the old SLIC group? Or did Gemini make one of his own version?

              As far working together goes, I wouldn't mind that at all. In fact, I have already been thinking (and I *think* Don has too) to get a new SLIC group together for SLIC 2. It goes without saying that the people who I have in mind for this, presuming they have the time and energy for it, are Don, Darryl, Chris, you and myself (and one or two more people with SLIC expertise and/or good ideas). Anyway, that's something for the future...

              But SLIC 2 will probably be *very* different from SLIC 1 so there's not much point doing an anything but gathering ideas for what should be converted to or implemented in SLIC 2 (and hoping that it will be possible). And gathering ideas is something that anyone can do, whether you have SLIC knowledge or not. Basicly, one could simply go to the CtPII forums and put every suggestion and idea mentioned there on a list and try and implement as much of that list as possible in SLIC 2 once it's available, but that could just as well be done once CtPII is released as well. Maybe even better 'cause we will then have a much better idea of what will be possible and what not. What I'm trying to say is that IMHO we don't have a friggin' clue what SLIC 2 will be like and can't do anything meaningfull until we do.

              I do agree that writing down code that we already have (or that we've been working on but what doesn't work yet) would be usefull. That would be put on top of the list with stuff that should be converted to SLIC 2. We might even be able to help each other out if we're stuck with something.
              When I get home tonight (I'm at my university now), I'll see if I can find the Leonardo's Workshop code, I started that a long time ago but never finished it because of unexplained bugs and other (non-CtPI) things that came up. Maybe one of the guys has an explanation for the bugs. Any other code that I have (all from the old SLIC group) is either already in your mod (apart from the Guerrilla/Partisan thing, it's basicly done but no-one ever did anyting with it) or not in an advanced enough state to share with others (i.e. more idea then actual code).

              Anyway, I'm also leaving town tonight and I'll be gone for a few days (I'm going to Disneyland! ) and when I come back I have exams to study for so I'm not sure if I can actually post the LW code (or anything else for that matter) before the middle of next week.
              [This message has been edited by Locutus (edited October 04, 2000).]
              Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

              Comment


              • #22
                Well the triggers I have are pretty much described in this thread:

                advance discovery effects:
                Dissemination.

                city.captured effects:
                Refugees.

                turn based average City Pop effects (ie punishments for ICS)
                PopMigration and B-Tax merged into one trigger for speed.

                turn based average Score effects (ie punishments for the runaway civ)
                Terrorist strikes.

                The last one is still testing but I think all the bugs are out... I just can't speak to balance.
                In addition I might make things a little more varied than the simply pop killed effect there is now (such as unit killed, land pillaged, improvement detroyed- which I don't think I can do, etc etc).

                My next project is the Popular Uprising which started this thread.
                I have also considered random natural disasters like Earthquakes, local Flooding, Epedemics etc etc...

                I have never actually tried and failed to get an idea to work. I'm pretty determined. I'm sure I have dismissed ideas as infeasible or too complex to execute quickly... such as the variable improvement costs based on city pop... basicly anything that requires two or more nested loops disuade me.

                And of course I wait gleefully for SLIC2 but without a hint of docs I must agree with Locutus. Not much to do but wait.

                What would I like to see? Well control over improvements within the city would be nice.
                Built in fields like discovery.name would be great or at least the ability to assign an advance to an index in the current context.
                But I think this above all:
                User defined Arrays.

                With arrays and a mapping from discovery.type to the DB string I could make disseminate generic for any mod instead of custom code for every advance set.

                Having said that however I suspect the disseminate and other gossip events like maps and military readiness were intended for CTPI and will likely be finished in CTPII.

                Gedrin

                Comment


                • #23
                  Hi guys, Nope, I never made a partisan trigger for anything but my own scenario. And it was designed for the scenario so unfortunately it would be not useful outside of that.

                  Yes, I am looking forward to slic2. I really can't wait to see what's going to be all added and improved. Hey, I'm sure I can spare some time the the new slic group Locutus so please keep me in mind. Thxs.

                  Gedrin, that's just what I was thinking. If slic2 allows arrays there is so much more we could do.

                  The one thing I hope, really hope is in slic2 is the ability to destroy and build improvements.


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

                  Comment


                  • #24
                    Oh and I thought of one more thing I would like:

                    Either no functions that operate only within a Button or message box... or deliever messages and alertboxes to the AI and have a default button selection... like OK if it's the only one button there.

                    I wanted to try and create something to topple a governement but since SetGovernment only works in a button it does nothing to the AI.

                    Ooops I guess I did try and fail to do one.
                    Forgot about that.

                    Gedrin.

                    Comment


                    • #25
                      Alright, I'm getting torqued.

                      I have the following in my Terrorist trigger:
                                                        SetPlayer(1,g.player);
                      // The following = Random(3) - 2 - (player.1.score - average)/average
                      // where average = totalScore/numberPlayerLeft
                      strikes = Random(3) - 3 + (player.1.score * numberPlayersLeft / totalScore);
                      // The chances that a terrorist strike kills a civ's last city is small but not nil
                      while ((strikes > 0) && (cityCount > 0)) {



                      And while the comment has an error, is should be:
                      // The following = Random(3) - 2 + (player.1.score - average)/average
                      The line in my code is what I really want:
                      strikes = Random(3) - 3 + (player.1.score * numberPlayersLeft / totalScore);

                      Now I know the trigger does what I want when the conditions are met because if I use:
                      strikes = Random(3) + 3 + (player.1.score * numberPlayersLeft / totalScore);
                      it fires 3 to 5 times a turn but, now matter how big my score gets:
                      player.1.score * numberPlayersLeft / totalScore = 0
                      (truncated of course because its an int)

                      So what the heck am I missing?

                      This value is supposed to be:
                      =player.1.score/average
                      =player.1.score/(totalScore/numberPlayersLeft)
                      =player.1.score*numberPlayersLeft/totalScore

                      right?

                      Is there something more in the human player score not in the AI score? Not that I think that matters because I've had some stupid large scores by virtue of the cheat mode and still the value never exceeds 0.

                      Does anyone know why?
                      Ok I just thought of something... does slic do divisions first?
                      I also tried and failed and display player.1.score in the message.
                      I've tried reducing scores by g.maxscore - 3600 which is the diff bonus and reducing scores by 75*(numberOfPlayers-1) which is the Opponents bonus.
                      No change. Grrr... Insights anyone?

                      Gedrin

                      Comment


                      • #26
                        Um so it appears that:
                        trigger 'AveScoreBasedEffects' when (g.player) {

                        fires for g.player == 0 it is not considered true and therefore the code does not trigger.
                        To trigger for every player requires
                        when (g.player >= 0)

                        Don't you hate it when you just have to say to yourself... Doh... I should have seen that sooner.



                        Anyway my Terrorist trigger is now being tested for play balance.
                        I think
                        score/average - 3 + Random(3)
                        will actually be a little insigificant.

                        On another note:
                        The power graph does not include score bonuses for difficulty, opponents, or map size.
                        player.score however does so if anyone else is ever using it keep that in mind.
                        Difficulty bonus = g.maxscore - 3600 if it is unchanged from the box.

                        Gedrin

                        Comment


                        • #27
                          Well, I dug into my archives and found a file that contains most, if not all, of the code developped by the SLIC group or me. I put it up on my website, you can download it here. I doubt this file will actually work, a lot of it is incomplete or doesn't work at all. It would be great if anyone could tell me what's wrong with the Leonardo's Workshop code (apart from the fact that it's butt-ugly and probably inefficient code ), that took a lot of time to code but for some reason doesn't seem to work.

                          The stuff that (should) work:

                          - Guerrilla/Partisan trigger: creates guerrilla units when a city is captured (should IMHO still be refined but at least it works )
                          - Check contents of stack: let's you view the contents of an enemy stack
                          - Flat map code: nothing new, already in MedMod
                          - Garrison code: nothing new here either.

                          I know, it ain't much but still...

                          Gotta run,

                          Locutus

                          Edit: Damn, screwed that whole post up and couldn't edit it until now because my Internet connection gave up on me.
                          [This message has been edited by Locutus (edited October 13, 2000).]
                          Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

                          Comment

                          Working...
                          X