Announcement

Collapse
No announcement yet.

The Ages Of Man

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #46
    Originally posted by Martin Gühmann
    But that isn't a problem of the Playtest only.
    In a way, it is. After having encountered some crashes, I have changed the playtest to return 0 when accessing an invalid reference, rather than the value of an uninitialised variable. But it may be that the uninitialised variable actually had a "correct" value, due to the particular order of Slic statements. As an example, assume you have the following code in a Slic handler that has city[0], but does not have player[0].
    Code:
    player[0] = city[0].owner;
    if (IsHumanPlayer(player[0]) ...
    You will get 2 Slic errors on execution, because index 0 is out of bounds in the player array. The assignment in the first line will fail, but the Activision version may just have stored the evaluated city[0].owner value in the variable that is being accessed when evaluating player[0] in the condition. Everything seems to work as designed, the Mod maker is happy, and tells you to always run with DebugSlic off to suppress the warnings . And warns you not try to modify this code at home. When you insert another statement between the 2 lines, it suddenly may stop working as intended, and may even cause a crash to desktop (though probably not with this particular example).

    With the playtest release, the condition will never be executed, because the invalid player[0] reference is replaced with 0 (= barbarians, when interpreted as a player).

    Of course, the best solution is to correct the Slic code and use
    Code:
    if (IsHumanPlayer(city[0].owner) ...
    or store the city[0].owner value in some other variable.

    Comment


    • #47
      "if (IsHumanPlayer(city[0].owner)"
      Ok, that solution is Ok for that particular case, but what do you do where:

      "if (IsHumanPlayer(player[0])}"
      Is used so that a code only executes once a turn.

      Comment


      • #48
        Originally posted by Fromafar
        In a way, it is. After having encountered some crashes, I have changed the playtest to return 0 when accessing an invalid reference, rather than the value of an uninitialised variable. But it may be that the uninitialised variable actually had a "correct" value, due to the particular order of Slic statements. As an example, assume you have the following code in a Slic handler that has city[0], but does not have player[0].

        Code:
        player[0] = city[0].owner;
        if (IsHumanPlayer(player[0]) ...
        You will get 2 Slic errors on execution, because index 0 is out of bounds in the player array. The assignment in the first line will fail, but the Activision version may just have stored the evaluated city[0].owner value in the variable that is being accessed when evaluating player[0] in the condition.
        That's indeed a serious problem, because the mods are full of them. And you can't do some certain things:

        Code:
        player[0] = city[0].owner;
        PW = player[0].publicworkslevel;
        Assume again the event has a city parameter but no player parameter. As there is no other way to retrieve the player's public works level. This doesn't work and therefore my City Capture Options script is broken. At least I was able to assume that this works at least. Of course the intendet solution is that the array is filled.

        Originally posted by Fromafar
        Everything seems to work as designed, the Mod maker is happy, and tells you to always run with DebugSlic off to suppress the warnings . And warns you not try to modify this code at home. When you insert another statement between the 2 lines, it suddenly may stop working as intended, and may even cause a crash to desktop (though probably not with this particular example).
        Actual I did a lot of work to get rid of all the DebugSlic = Yes errors in GoodMod so that GoodMod is indended to be played with DebugSlic = Yes. And I was also aware of this problem so that I could code it in that way.

        Originally posted by Fromafar
        Of course, the best solution is to correct the Slic code and use
        Code:
        if (IsHumanPlayer(city[0].owner) ...
        or store the city[0].owner value in some other variable.
        Well that's right for code that is intended to work on the Activision versions. But I consider this forgetting of the value of the built in arrays as bug.

        Originally posted by stankarp
        "if (IsHumanPlayer(city[0].owner)"
        Ok, that solution is Ok for that particular case, but what do you do where:

        "if (IsHumanPlayer(player[0])}"
        Is used so that a code only executes once a turn.
        Actual it isn't used so that the code only executes once a turn it is used so that the code only executes if the player is human.

        So now to the question if the event that your event handler triggers on has a player, no problem. Otherwise you always has something like this before:

        Code:
        player[0] = something_that_represents_an_player_index;
        So all you have to do is to replace player[0] by the variable that is right of the assignement.

        And if you need something I described above you have to refill the player[0] again right before you have to use it of course in the Activision versions.

        -Martin
        Civ2 military advisor: "No complaints, Sir!"

        Comment


        • #49
          Clarification:
          "code only executes once a turn."
          Means once in total in a turn, rather than once in each players turn.

          IW wrote a short peice of code for me that I expanded on but rather than run it once for each player, he used :
          "if (IsHumanPlayer(player[0])}"
          so it runs only once in a full turn (ie, full turn = all player moves).

          Returns no slic errors with debugslic on yes, and
          no noticeable problems if played with debugslic on no.

          Comment


          • #50
            Originally posted by stankarp
            IW wrote a short peice of code for me that I expanded on but rather than run it once for each player, he used :
            "if (IsHumanPlayer(player[0])}"
            so it runs only once in a full turn (ie, full turn = all player moves).

            Returns no slic errors with debugslic on yes, and
            no noticeable problems if played with debugslic on no.
            This is probably because the code is in an event handler that does have a player[0], so in this case the code is valid.

            Comment


            • #51
              Originally posted by stankarp
              Clarification:
              "code only executes once a turn."
              Means once in total in a turn, rather than once in each players turn.
              I know what you mean.

              Originally posted by stankarp
              IW wrote a short peice of code for me that I expanded on but rather than run it once for each player, he used :
              "if (IsHumanPlayer(player[0])}"
              so it runs only once in a full turn (ie, full turn = all player moves).
              But nevertheless this doesn't run once per full turn, it may be only runs once per full turn if you have only one human player in the game, then indeed it runs once per full turn. But no one forces you to player a single player game.

              Actual it does make sense to run code for each human player in game.

              If you really want to run code once per turn then you should do this:

              Code:
              HandleEvent(BeginTurn)'EventHandlerWhatEver'pre{
                   if(g.player == 1){
                        // Do stuff here (Code1)
                   }
              }
              Alternatively you can do something like this since the BeginTurn event has a player argument:

              Code:
              HandleEvent(BeginTurn)'EventHandlerWhatEver'pre{
                   if(g.player == 1){
                        // Do stuff here (Code1)
                   }
              }
              Indeed Code1 is only executed once per full turn. Unlike this code:

              Code:
              HandleEvent(CityBeginTurn)'EventHandlerWhatEver'pre{
                   if(g.player == 1){
                        // Do stuff here (Code2)
                   }
              }
              Here Code2 is not executed once per full turn, it is executed as often as many cities player 1 has, because the CityBeginTurn event is called for each city of a player.
              Civ2 military advisor: "No complaints, Sir!"

              Comment


              • #52
                Originally posted by Martin Gühmann
                And you can't do some certain things:
                Code:
                player[0] = city[0].owner;
                PW = player[0].publicworkslevel;
                It would be interesting to know whether assignable arrays actually exist in the Activision 1.0 and 1.1 releases. Maybe it is all just suggestion, and even something like
                Code:
                player[3] = city[0].owner;
                PW = player[5].publicworkslevel;
                would give you "city[0].owner.publicworkslevel" .

                For the "once a turn" actions, I would suggest using a BeginTurn handler, and either using/storing the turn value, or testing against player[0] == 0. As remarked before, there could be multiple human players. And, even when there is a single human player, its index does not have to be 1. Tthe barbarians should always exist, but player 1 may have been killed.

                Comment


                • #53
                  Originally posted by Fromafar

                  It would be interesting to know whether assignable arrays actually exist in the Activision 1.0 and 1.1 releases. Maybe it is all just suggestion, and even something like
                  Code:
                  player[3] = city[0].owner;
                  PW = player[5].publicworkslevel;
                  would give you "city[0].owner.publicworkslevel" .
                  Well the only problem with this syntax is that it doesn't work. And if I look into tut2_main.slc then I see a very strong suggestion that it is supposed to work like that.

                  -Martin
                  Civ2 military advisor: "No complaints, Sir!"

                  Comment


                  • #54
                    "PW = player[5].publicworkslevel;"

                    I had a major problem with the supply code for the human in AOM, at one stage about turn 150-200, the human started getting an AI players PW cheat. At Peter Triggs' sugestion, I changed a player[5] reference used in the code and the problem stopped.

                    Comment


                    • #55
                      Originally posted by Martin Gühmann
                      Well the only problem with this syntax is that it doesn't work.
                      Does this statement mean that you have tested the resulting PW value of
                      Code:
                      player[3] = army[0].owner;
                      PW = player[5].publicworkslevel;
                      and found it to be different from
                      Code:
                      player[0] = army[0].owner;
                      PW = player[0].publicworkslevel;
                      when using an Activision (which?) version?

                      Or does it mean something else?

                      Comment


                      • #56
                        Originally posted by Fromafar
                        Or does it mean something else?
                        Actual I mean this:

                        city[0].owner.publicworkslevel;

                        At least it was a long time ago when I tested it.

                        But I can't remember to have seen something that would allow this in the parser generator files.

                        -Martin
                        Civ2 military advisor: "No complaints, Sir!"

                        Comment


                        • #57
                          OK, I probably should have worded this better in my post. "city[0].owner.publicworkslevel" is invalid as Slic code. It was not intended to denote actual code, but rather to express that you might still get the actual value of the public works of city[0].owner, even when using completely unrelated indices in the 2 statements.

                          Comment


                          • #58
                            Actual my point was that this what the syntax implied can't be done with the source code edition even if you use the dirty workaround that worked in the original version.

                            Maybe this feature is already broken in the original version, but at least it was working partially. But now it is broken and all the mods are incompatible. Maybe instead of fixing all these virtual problems with the *.ldl files you should have a look on this.

                            -Martin
                            Civ2 military advisor: "No complaints, Sir!"

                            Comment


                            • #59
                              The virtual .ldl file problems are real enough to crash my AOM test setup.

                              And I intend to change the source code to make the mods work again. I don't have the original versions installed at the moment, so I would like someone to report what the results of the tests in my earlier posts are. We can not rule out the possibility that the original Activision version(s?) actually contained assignable arrays. This would be a better design, but probably more difficult to implement than just restoring the read from random memory and hope for the best. Like the above, I have only "fixed" this because I got an actual crash in a test game.

                              Comment


                              • #60
                                Originally posted by Fromafar
                                The virtual .ldl file problems are real enough to crash my AOM test setup.
                                Well obviously we got two different sets of altered *.ldl files for AOM, I just got a controlpanel.ldl. And with just this files a lot of these *.ldl problems seems to be virtual. But for the future mention the mod for that you do such *.ldl fixes.

                                Originally posted by Fromafar
                                And I intend to change the source code to make the mods work again. I don't have the original versions installed at the moment, so I would like someone to report what the results of the tests in my earlier posts are. We can not rule out the possibility that the original Activision version(s?) actually contained assignable arrays. This would be a better design, but probably more difficult to implement than just restoring the read from random memory and hope for the best. Like the above, I have only "fixed" this because I got an actual crash in a test game.
                                It seems the problem is more complicated. But first some test code:

                                Code:
                                HandleEvent(ArmyClicked)'MG_TestSomething'pre{
                                	player[3] = army[0].owner;
                                	int0 = player[3].publicworkslevel;
                                	int1 = g.player;
                                	int2 = player[3].publicworkslevel;
                                	player[5] = player[3];
                                	int3 = player[5];
                                	int4 = player[3];
                                	int5 = player[4];
                                	if(player[3] == player[5]){
                                //		AddEffect(army[0].location, "SPECEFFECT_FIRES", "SOUND_ID_PILLAGE");
                                	}
                                	if(army[0].owner == army[0].owner){
                                //		AddEffect(army[0].location, "SPECEFFECT_UNHAPPINESS_SEA", "SOUND_ID_EXPLOSION_LAND_1");
                                	}
                                	if(int3 == int4){
                                //		AddEffect(army[0].location, "SPECEFFECT_DIPLOMATIC", "SOUND_ID_EXPEL");
                                	}
                                	int6 = GetNearestWater(army[0].location, army[0].location);
                                	int7 = player[5].publicworkslevel;
                                	int_t i;
                                	for(i = 0; i < 10; i = i + 1){
                                		Event:CreatedArmy(army[0]);
                                //		AddEffect(army[0].location, "SPECEFFECT_UNHAPPINESS_SEA", "SOUND_ID_EXPLOSION_LAND_1");
                                	}
                                	int8 = player[5];
                                	int9 = player[3];
                                	MessageAll('MGMAETestMessage');
                                }
                                The int1 to int9 are global int_t's and MGMAETestMessage is a message box that displays all these intXs actual I can go to int30.

                                First observation: Doing something like this: int8 = player[88]; produces an indix out of bounce error if there was nothing assigned to the array by using a higher index than 88. That holds for version 1.0 and version 1.1.

                                Second observation all the statements like intX = player[X]; Well I didn't changed the player in between. That holds for both versions.

                                Third the statement if(player[3] == player[5]){ doesn't work in both versions. No special effect at the army's location. But the other two are there, of course if they aren't outcommented.

                                Something like int7 = player[5].publicworkslevel; does work in the given code context and in the test situation in version 1.1 but it does not work in version 1.0. Maybe they fixed something but they could have some interacting problems.

                                So probably a lot of work has to be done. But that is an essential feature to make mods to work as intended.

                                -Martin
                                Civ2 military advisor: "No complaints, Sir!"

                                Comment

                                Working...
                                X