Announcement

Collapse
No announcement yet.

creating natural disasters via SLIC????

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

  • #76
    quote:

    Originally posted by heardie on 01-13-2001 07:20 PM
    hmmm, I am a fool. It's always the simpilest errors that get you. It's the same with c++, they're a ***** to track down and when you see them, it is so obviouos.



    Yep, it's always those little things that do it. Fortunately, as you become more experienced, you get a nose for them and tracking them down becomes a lot easier (or at least that's what's happening with me).

    quote:


    Thanks a ton Loctus.



    Can't anyone write my name correctly anymore these days?

    quote:


    What would have been really cool was a debug window in the game where you cacn track variable values


    Tip: always make a few messageboxes pop up on command (pressing a key, ending a turn, moving a unit, whatever) that contain important information about variables and stuff. Almost as good as a debug window
    Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

    Comment


    • #77
      Jerk,

      Sorry, I seem to have overlooked your post for some reason.

      Thanks for all the hard work, it's much appreciated. But your findings are very strange and contradict my findings. I originally had it so that the Random function was performed everytime a player's turn began. This usually crashed the game after 2 or 3 players had had their turn. Then I made it so that the only time when the Random function was performed, was during the barbarian's turn. This caused the game to crash as soon as the Barbarians had their first turn, every single time. So my conclusion was that the Random function was broken. Now you're telling me it's the CutImprovements event that's broken and the Random function works fine. This sounds like a much better explanation but it doesn't explain my crashes. I will look into this in more detail when I have the chance (who's stupid idea was it to give a day only 24 hours? ) and prey that you're right and I made a mistake or whatever...
      Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

      Comment


      • #78
        Locutus,

        I played with this a little and from what I can tell, the Random IS broken. CtP2 just abends when using it.
        Don,
        CtPMaps (Hosted by Apolyton)

        Comment


        • #79
          Well, after testing I still maintain that it's still an issue with the Effect:cuttileimprovements(disasterloc) portion of the script. I believe that the effect has a problem working in spots where nobody is at or is yet to be uncovered. I have gone through and tested this several times. If I remove the effect and replace it with Terraform(disasterloc,17) I get no crash and it replaces the random tiles with a dead tile. If I go ahead and start a game, jot down the x and y for a tile near my city, replace the randoms with those set x and y coordinates it works with cuttileimprovement. If I rig the random number so x and y will fall around my city (Random(3) + mycityY,Random(3) + mycityY) it also works without a crash. I think that is the problem. The game doesn't work when you randomly pick a spot on the map early in the game when the overwhelming odds are that the spot will be an undiscovered portion of land. Try doing what I did to test this. Replace the cuttileimprovement with terraform(disasterloc,17). Then put that back, and try rigging the random choice to fall in your original city radius. I can reproduce the error by adding this little chunk of script into script.slc:
          Code:
          HandleEvent(BeginTurn) 'IWillCrash' post {
            location_t tmpLoc;
            location_t disasterLoc;
            if(g.year > 3) {
            MakeLocation(disasterLoc, 1, 1);
            Event:CutImprovements(disasterLoc);
            }
          }

          Comment


          • #80
            Locutus,

            It worked last time I tested it. It no longer works. I guess it wasn't the cuttileimprovements that is causing the damage. However, removing the random parts for picking the random x and y position and the richter and damage variables still produces a crash for me when the barbarians take their first turn (after my very first turn). I can also comment out everything under the "if (CityIsValid(tmpCity)) {" and it does not crash. This is why I don't think it's Random() causing the problem.

            Comment


            • #81
              I did some testing as well last night and couldn't recreate any kind of bug with the Random function, I generated random numbers up to 1000 and even generated hundreds of locations on my map using (the relevant part of) the above mentioned algorithm without problems. I tried to use the CutImprovements on a random location only twice and the game crashed immediately both times, so it would seem that it is indeed the CutImprovements event that's causing problems. I will look into this problem again tonight, since using it on a completely explored map crashed the game just as well as using it on a unexplored map (though I used the cheat menu to set the map explored, that might be the problem).
              [This message has been edited by Locutus (edited January 16, 2001).]
              Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

              Comment


              • #82
                Sorry, I kinda forgot all about this. I've been so busy helping on the Alex scenario.

                I found two functions that might be useful. TileHasImprovement(location, imptype) and CellOwner(location). TileHasImprovement is probably the one to use. If so, just add a for and an if to check to be sure there is actually an improvement to destroy before trying to destroy it. Sorry I didn't think about that and put it in my original code. I haven't looked to see what the values are for imptype. I might try to work on this tomorrow to add TileHasImprovement.

                Just an FYI, Random(500) has worked for hundreds of turns with no known problems in the Alex scenario.

                Comment


                • #83
                  Yes, I'm pretty sure Random isn't the problem. I suspect that checking with TileHasImprovement first and then killing the improvements will solve the problem, but I got hold up with some personal stuff last night so I didn't get to do my final testing on this. Hopefully tonight...
                  Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

                  Comment


                  • #84
                    I think I have it so it won't crash anymore. I replaced

                    Event:CutImprovements(disasterLoc2);

                    with

                    if (CellOwner(disasterLoc2) >= 1 && CellOwner(disasterLoc2) <=8) {
                    Event:CutImprovements(disasterLoc2);
                    }

                    Then did the same with the other CutImprovements. Watch it. One of the CutImprovements is just disasterLoc not disasterLoc2.

                    Thanks Jerk, for figuring out the problem.

                    I ran this over 40 times with no crash. It's possible I just got lucky, so it may still crash. In the random location part, I make it so that x & y are never < 2 or greater than maxX - 2 or maxY - 2. I figure that way it won't try to do something off the edge of the map. Though I think the CellOwner addition should probably solve the problem. I was still crashing with CellOwner >= 0, so I changed it to >= 1. I don't know what CellOwner returns if there is no owner. So barbarian areas will not have earthquakes, neither will unowned areas. That stinks. I was looking forward to having units wander around and get hit by an earthquake.

                    I still have a problem to work out before I post the entire revised code. Anybody know how to clear a city variable? Before I end the "if" below, I need to clear tmpCity or it won't change until it happens to hit another city and it never runs the non-city earthquake code again.

                    GetCityByLocation(disasterLoc, tmpCity);
                    if (CityIsValid(tmpCity)) {

                    Comment


                    • #85
                      Hmm, I put in the check for cellowner and used:
                      tmpCellOwner = CellOwner(disasterLoc);
                      if (tmpCellOwner >= 0) {
                      Event:CutImprovements(disasterLoc);
                      }
                      I got no crashes at all after adding this in the appropriate spots (wherever just CutImprovements was). Not sure right now why I didn't crash and yours did. I have altered the orignal posted code a bit (I threw in test messageboxes and stuff). By just putting the CutImprovements in the if statement it will still damage units wandering around the epicenter. I found that CellOwner returns -1 if its unowned. I have yet to have the script land on a barbarian city radius. I assume it would return 0 (the index number for barbarians). An interesting side note, I used the cheat menu to reveal the entire map, then place a barbarian city. When you hover over a tile you will see little information on the bottom under your control panel that says the owner of the tile or units there. Barbarian cities I placed did not seem to have any owned tiles. I could see the little white dashed line around the city that indicates its resource harvest border but they had no national border and under the control panel it did not say it was owned by anyone.
                      [This message has been edited by Jerk (edited January 18, 2001).]

                      Comment


                      • #86
                        Radical,
                        You don't have to clear the tmpCity variable. It's a local variable, right? That means that as soon as the eventhandler this variable is in stops executing, the tmpCity variable will be 'destroyed', it will no longer exist. In the next eventhandler you can't use it anymore because it won't exist anymore and when at some later point the same eventhandler is called again, it won't know the tmpCity variable either, it will declare a new variable that's also called tmpCity, but this isn't the same variable, it just happens to have the same name. Thus it won't have a valid city in it either and hence there's no need to worry about the code never not executing.

                        I encountered some problems with this several times with eventhandlers that were pre, but I haven't figured out the details of this yet. So whenever you can, use post instead of pre and also, test your code to verify that I'm correct, just to be sure.

                        BTW if you really need to, you can get an invalid city in a city-variable by taking a random neighbor of another, valid, city location and use GetCityFromLocation to assign the city at that location (which doesn't exist because cities are AFAIK always 1 tile apart minimum) to your city variable.

                        Jerk,
                        Hmm, I'd swear I've seen barbarian national borders in the past. Maybe this only happens when barbarians conquer existing cities? You could try to do that. Create a bunch of empty cities and an army of barbarians next to each of them. Then move them in (I think you can do this manually from the cheat menu when you have player 0 selected and you open the unit-section of the cheat menu). If it's not that it's probably a pre-patch or pre-release thing. The best way to test if it works for barbarians is of course to create barbarian cities all over the place so the odds that barbarians will be hit is relatively large.
                        Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

                        Comment


                        • #87
                          Jugding from the code you posted the problem seems to be in disasterLoc, not in tmpCity, but then again, you'd have to post the entire code before I can draw any conclusions about it. If you don't want to post the entire code, put it on a website (if you don't have a website, email me, I'll post them on my website for you). That way anyone that wants to figure out what the problem is, can look at the whole code. You can't draw any conclusions if you don't have all the code. It's like watching a game of football: watching only the first half isn't enough to say who will win (well, not in most cases anyway )...

                          Building index (as well as any other index): AFAIK it's the order in buildings.txt that determines this. So the first building is 0, the second 1, etc. For the standard game this means 0 = Academy, 1 = Airport, etc. If you're gonna use this info, double check this though, I'm fairly certain of this but not 100%.
                          Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

                          Comment


                          • #88

                            Is it possible to access the player built in variables for a civ that is not player[0]? With this quake mod I would like to message the human player if a quake hits another civilization. Any attempts to do this so far have resulted in slic syntax or out of bounds errors. To do this I would like to use the results of CellOwner() when its >= 0 like in my previous post. If I try to use player[tmpCellOwner].country_name I get out of bounds errors. I get a syntax error if I try player.tmpCellOwner.country_name. forcing player[0] = tmpCellOwner doesnt cause a slic error when it does player[0].country_name but it also doesn't work (it's not getting set to the country name at all). I am probably overlooking something simple. Help appreciated.

                            Comment


                            • #89
                              Well, I'm probably missing something or have something in the wrong place but as far as I can tell tmpCity is not cleared, reinitialized or whatever. I know that's the way it should work but it doesn't appear to be working that way.

                              Here's the code with most comments removed. I didn't include the QuakeDamage function since I don't believe it's causing a problem. I haven't changed that anyway. I also took out most of the buildings and elseifs to take up less space. That section has not changed. I just added the relevent stuff from my string file at the bottom so you could see what I'm displaying. Right now it's set where x is always 4 and y is set so I have a good chance of hitting 2 cities on my test map.

                              Everything appears to work fine until it hits a city the first time. Then the EQHitCity message displays every time with the first city name until it hits the other city. Then the 2nd city's name displays until it hits another city.

                              Until the first city is hit, EQWhatCity prints city[0].name. After the first city is hit EQWhatCity displays the city name that was hit the previous turn and then continues to display that name until another city is hit.

                              Once the first city is hit, EQNoCity never displays again.

                              The x and y values continue to change. In this code just y, since I have x fixed at 4 for testing. I shouldn't say never, I advanced maybe 15 turns max after hitting the first city.


                              Locutus, I'll send you the complete set of files.

                              Jerk, this is displaying a message every turn, regardless of where it hits. Very annoying really, but I won't have quakes occuring every turn in my final version. Doesn't solve your problem exactly, since you want the civ. You probably know how to display without the civ anyway.


                              //////////////////////
                              // Global variables //
                              //////////////////////

                              int_t humanPlayer;
                              int_t tmpYloc;
                              int_t tmpXloc;
                              int_t turnCount;
                              int_t turnMax;

                              #include "EQ_func.slc"

                              //---------------------------------
                              // Stuff to do when the game starts
                              //-----------------------------------

                              HandleEvent(BeginTurn) 'EQStart_F' pre {
                              int_t tmpPlayer;
                              if(IsHumanPlayer(player[0])) {
                              humanPlayer = player[0];
                              turnMax = 600;
                              turnCount = 0;
                              DisableTrigger('EQStart_F');
                              }
                              }

                              //-----------------------
                              // Stuff to do every turn
                              //-------------------------

                              HandleEvent(BeginTurn) 'EQEachTurn_F' post {
                              city_t tmpCity;
                              int_t i;
                              int_t tmpPlayer;
                              int_t tmpRichter;
                              int_t tmpDestroy;
                              int_t tmpnumberUnits;
                              location_t disasterLoc;
                              location_t disasterLoc2;

                              tmpPlayer = player[0];
                              //tmpXloc = Random(62);
                              tmpYloc = Random(10) + 87;

                              //if (tmpXloc < 2) {
                              tmpXloc = 4;
                              //}
                              if (tmpYloc < 2) {
                              tmpYloc = 2;
                              }

                              if (tmpPlayer == 1) {
                              turnCount = turnCount + 1;
                              if (turnCount > turnMax) {
                              if (humanPlayer == 1) {
                              Event:GiveMap(2,1);
                              }
                              } // temp for testing take out later
                              MakeLocation(disasterLoc, tmpXloc, tmpYloc);
                              tmpRichter = Random(9);
                              tmpDestroy = Random(53);
                              // value[0] = tmpRichter;
                              city[0] = tmpCity;
                              Message(1, 'EQWhatCity');
                              GetCityByLocation(disasterLoc, tmpCity);
                              if (CityIsValid(tmpCity)) {
                              value[0] = tmpRichter;
                              city[0] = tmpCity;
                              Message(1, 'EQHitCity');
                              tmpnumberUnits = UnitsInCell(disasterLoc);
                              if (tmpnumberUnits > 0) {
                              QuakeDamage (disasterLoc, tmpnumberUnits, tmpRichter);
                              }
                              for (i = 0; i < tmpRichter; i = i + 1) {
                              GetRandomNeighbor(disasterLoc, disasterLoc2);
                              if (CellOwner(disasterLoc2) >= 1 && CellOwner(disasterLoc2) <=8) {
                              Event:CutImprovements(disasterLoc2);
                              }
                              tmpnumberUnits = UnitsInCell(disasterLoc2);
                              if (tmpnumberUnits > 0) {
                              QuakeDamage (disasterLoc2, tmpnumberUnits, tmpRichter);
                              }
                              }
                              if (tmpRichter > 5) {
                              if (tmpDestroy == 0 | | tmpDestroy == 1) {
                              DestroyBuilding(tmpCity, BuildingDB(IMPROVE_VR_AMUSEMENT_PARK));
                              } elseif (tmpDestroy == 2) {
                              DestroyBuilding(tmpCity, BuildingDB(IMPROVE_ACADEMY));
                              // lots more elseifs and buildings between these 2 lines
                              } elseif (tmpDestroy == 52) {
                              DestroyBuilding(tmpCity, BuildingDB(IMPROVE_UNIVERSITY));
                              }
                              if (tmpRichter == 8) {
                              DestroyBuilding(tmpCity, BuildingDB(IMPROVE_CITY_WALLS));
                              }
                              }
                              } else {
                              value[0] = tmpRichter;
                              Message(1, 'EQNoCity');
                              if (CellOwner(disasterLoc) >= 1 && CellOwner(disasterLoc) <=8) {
                              Event:CutImprovements(disasterLoc);
                              }
                              tmpnumberUnits = UnitsInCell(disasterLoc);
                              if (tmpnumberUnits > 0) {
                              QuakeDamage (disasterLoc, tmpnumberUnits, tmpRichter);
                              }
                              for (i = 0; i < tmpRichter; i = i + 1) {
                              GetRandomNeighbor(disasterLoc, disasterLoc2);
                              if (CellOwner(disasterLoc2) >= 1 && CellOwner(disasterLoc2) <=8) {
                              Event:CutImprovements(disasterLoc2);
                              }
                              tmpnumberUnits = UnitsInCell(disasterLoc2);
                              if (tmpnumberUnits > 0) {
                              QuakeDamage (disasterLoc2, tmpnumberUnits, tmpRichter);
                              }
                              }
                              }
                              }
                              }

                              #include "EQ_msg.slc"

                              EQ_NO_CITY "An earthquake of magnitude {value[0]} has struck {tmpXloc}, {tmpYloc}."
                              EQ_HIT_CITY "An earthquake of magnitude {value[0]} has struck the city of {city[0].name} at location {tmpXloc}, {tmpYloc}."
                              EQ_WHAT_CITY "What! An earthquake of magnitude {value[0]} has struck the city of {city[0].name} at location {tmpXloc}, {tmpYloc}."

                              Comment


                              • #90
                                I think I'll replace my fix with Jerk's fix and see if I have any problems. When I crashed I was thinking the unowned tiles might return 0, so that's why I changed it to >= 1.

                                I've seen the barbarian borders before but I'm sure I only saw them when they capture a city. I've never placed a barbarian city.

                                tmpCity is local but it seemed to stick once I hit a city. I need to do further testing and have the x,y appear in a message box so I can determine exactly what is happening. I'll have to create more messages for testing. I should have posted more of the code and explained why I think I need to clear tmpCity.

                                GetCityByLocation(disasterLoc, tmpCity);
                                if (CityIsValid(tmpCity)) {
                                city[0] = tmpCity;
                                value[0] = tmpRichter;
                                Message(1, 'EQHitCity');

                                On turn thirty-something a quake hit a city. Every turn after that I got a message that the same city was hit. It did not appear to "really" be hitting the same city since the units were not being damaged. It's very unlikely to hit a city on any given turn, so CityIsValid(tmpCity) should have been false and I should not even get the message that a city was hit. Once I display the x,y coords I'll know what is really happening and probably find I have a mistake somewhere.

                                I'd post the whole thing but I'm leaving the buildings the way I had them, so there's a million lines. Someone wanted (and I might want this also) to be able to give certain buildings a greater or lesser chance of being destroyed. I think leaving the buildings all listed, adjusting the random #, then adding or's for the new random #'s is the easiest way to do that.

                                If I knew what building was a certain index #, I might use a different method. That's a problem I've been running into a lot. What's the best way to determine index numbers for buildings, tile improvements, etc? Are they listed somewhere? I really wanted to use TileHasImprovement instead of CellOwner but one of the tileimp files I looked at had terraform stuff in it. I think that was the icon file for TI. Is it as simple as the order they are listed in in the text files?

                                Thanks again for the help.


                                Comment

                                Working...
                                X