Announcement

Collapse
No announcement yet.

Another disapointing Slic attempt

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

  • Another disapointing Slic attempt

    I tried to do a code about a nuclear explosion disaster. I wrote the code but i am getting syntax errors everytime i load the game with it.
    So can anyone help this unhappy slic newbie. And also point out changes to help me became a better slicer.

    Code:
    HandleEvent(BeginTurn) 'NuclearBoom' post {
    city_t	tmpcity;
    int_t		tmpplayer;
    int_t		i;
    int_t		randomnum;
    
    message(tmpplayer, 'NuclearBoom');
    
    tmpcity = city[0];		 
    tmpplayer = player[0];		
    	
    GetCityByIndex(player[0], i, city[0]);
    	for(i=0; i< player[0].cities; i=i+1) { 						// Scroll over all cities
    		if(CityHasBuilding(city[0], "IMPROVE_NUCLEAR_PLANT")){		// if city has Nuclear Plant
    			randomnum = random(300);						// there is a 300 Chance. 						
    			if(randomnum == 0){							// of happenning
    				Event: NukeCity(city[0], player[0]); 			// a nuclear explosion (nuke).
    					if(HasAdvance(player[0], ID_ADVANCE_FUSION)) {	// But if player has Fusion
    						randomnum == randomnum - 10000;		// nothing happens.
    					}
    			} 
    		}	
    	}
    }
    - Thanks in advance
    "Kill a man and you are a murder.
    Kill thousands and you are a conquer.
    Kill all and you are a God!"
    -Jean Rostand

  • #2
    I am feeling really stupid. After post this thread. I decided to download edit plus. And with it i found that the syntax error was actually a stupid wrong symbol. I have fix it the post.
    But i will leave this code here so that more experienced modders can point out some changes to improve it for me.
    "Kill a man and you are a murder.
    Kill thousands and you are a conquer.
    Kill all and you are a God!"
    -Jean Rostand

    Comment


    • #3
      Re: Another disapointing Slic attempt

      Code:
      if(randomnum == 0){	// of happenning
      Event: NukeCity(city[0], player[0]);	// a nuclear explosion (nuke).
      if(HasAdvance(player[0], ID_ADVANCE_FUSION)) {	// But if player has Fusion
      randomnum == randomnum - 10000;	// nothing happens.
      }
      }
      This code will give you a nuke explosion also the player has Fusion.

      Also this line is something different you actual want:

      Code:
      randomnum == randomnum - 10000;	// nothing happens.
      It will ask if randomnum is equal to randomnum - 10000, I would say this is never true. So in slic it will be interpreted as 0 and that doesn't do anything there.

      To achieve what you want I would add to the condition if randomnum is equal to 0 the condition if the player do not own the advance fusion. So my could would look like:

      Code:
      if(randomnum == 0//if randomnum equal to 0
      && !HasAdvance(player[0], ID_ADVANCE_FUSION) //and player does not own fusion
      ){	// do the following
      Event: NukeCity(city[0], player[0]);	// a nuclear explosion (nuke).
      }
      -Martin
      Civ2 military advisor: "No complaints, Sir!"

      Comment


      • #4
        Re: Another disapointing Slic attempt

        Originally posted by Pedrunn
        Code:
        HandleEvent(BeginTurn) 'NuclearBoom' post {
        city_t	tmpcity;
        int_t		tmpplayer;
        int_t		i;
        int_t		randomnum;
        
        message(tmpplayer, 'NuclearBoom');
        
        tmpcity = city[0];		 
        tmpplayer = player[0];
        You should switch the line "message(tmpplayer, 'NuclearBoom');" and "tmpplayer = player[0];". As it is, you first declare the variable tmpplayer ("int_t tmpplayer;") - after which it has the default value 0 - then you send the message and only then you assign the player who's turn it is to tmpplayer. So as it is, the message will always be sent to the barbarians (= player 0). When you place the assignment part before the message-send part, the message will actually be sent to the player whose city is being nuked.

        Note however, that with this code you're sending the message every turn. If you only want the message to be sent when a city is actually being nuked, put it directly in front of or behind the Event:NukeCity line.
        Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

        Comment


        • #5
          Re: Re: Another disapointing Slic attempt

          Originally posted by Martin Gühmann
          Code:
          if(randomnum == 0//if randomnum equal to 0
          && !HasAdvance(player[0], ID_ADVANCE_FUSION) //and player does not own fusion
          ){	// do the following
          Event: NukeCity(city[0], player[0]);	// a nuclear explosion (nuke).
          }
          Thanks Martin i did not like that part of the code. I knew somethinh was wrong with it. I will change it now.

          Originally posted by Martin Gühmann
          Note however, that with this code you're sending the message every turn. If you only want the message to be sent when a city is actually being nuked, put it directly in front of or behind the Event:NukeCity line.
          I did no know that. I will change the place of it. A regarding the message to barbs. message is this. so i declare i want it for the human player. So still it is going to send to player 0. Anyway i will switch it now too
          Code:
          Alertbox 'NuclearBoom' {
          	Show();
          	Title(ID_NUCLEAR_BOOM_TITLE);
          	if (IsHumanPlayer(player[0])) {
          		Text(ID_NUCLEAR_BOOM_US);
          		Eyepoint(city[0]);
          	}else {
          		Text (ID_NUCLEAR_BOOM_THEM};
          	}
          }
          "Kill a man and you are a murder.
          Kill thousands and you are a conquer.
          Kill all and you are a God!"
          -Jean Rostand

          Comment


          • #6
            What you guys think?

            Code:
            HandleEvent(BeginTurn) 'NuclearBoom' post {
            city_t	tmpcity;
            int_t		tmpplayer;
            int_t		i;
            int_t		randomnum;
            
            tmpcity = city[0];		 
            tmpplayer = player[0];		
            	
            GetCityByIndex(player[0], i, city[0]);
            	for(i=0; i< player[0].cities; i=i+1) { 						// Scroll over all cities
            		if(CityHasBuilding(city[0], "IMPROVE_NUCLEAR_PLANT")){		// if city has Nuclear Plant
            			randomnum = random(300);						// there is a 300 Chance. 						
            				if(randomnum == 0							//if randomnum equal to 0 
            				&& !HasAdvance(player[0], ID_ADVANCE_FUSION)){		// and players doenst have fusion 
            					Event: NukeCity(city[0], player[0]);		// a nuclear explosion (nuke).
            					message(player[0], 'NuclearBoom');			// and a warning message will appear
            				} 
            			
            		}	
            	}
            }			
            
            Alertbox 'NuclearBoom' {
            	Show();
            	Title(ID_NUCLEAR_BOOM_TITLE);
            	if (IsHumanPlayer(player[0])) {
            		Text(ID_NUCLEAR_BOOM_US);
            		Eyepoint(city[0]);
            	}else {
            		Text (ID_NUCLEAR_BOOM_THEM};
            	}
            }
            Anything else?
            "Kill a man and you are a murder.
            Kill thousands and you are a conquer.
            Kill all and you are a God!"
            -Jean Rostand

            Comment


            • #7
              Looks good to me...
              Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

              Comment


              • #8
                First, here's a background comment on events and builtin variable arrays. If you look at the Activision SLIC Events document you see events described as:


                BeginTurn(int_t, int_t)
                Begin a player's turn

                CityBeginTurn(city_t)
                Main city begin turn event

                CreateCity(int_t, location_t, int_t, int_t [, city_t])
                Create a city (first int is cause, second int is unit type that settled (-1 if not from unit)

                AddGold(int_t, int_t)
                Add gold to player
                Here the "int_t", "location_t", and so on define the type of variable you have to use when you want to generate one of these events. For example, to give 100 gold to the first player in the game (usually the Human), you'd write "Event:AddGold(1,100);"

                It's a bit different when events turn up in the head of an event handler. In this case the above descriptions might be better written as:

                BeginTurn(player[0], value[0])

                CityBeginTurn(city[0])

                CreateCity(player[0], location[0], value[0], value[1] [, city[0]])

                AddGold(player[0], value[0])
                These "player[0]", "location[0]", "value[0]", and so on aren't visable in the head of the handler but are filled in when the handler is called. For example, when you write a handler:

                Code:
                HandleEvent(BeginTurn) 'Example' pre {
                
                       stuff
                
                }
                You have a "player[0]" and "value[0]" (= the game turn) to play with. These are the only builtin variables that will automatically have values when this handler triggers. So when you write "tmpcity = city[0];" as you did above, you'll get a "Variable 0 Out of Bounds" error: there is no city[0] in this context.

                This is not to say that you can't assign a value to a builtin variable. For example, one could have:

                Code:
                     GetCityByIndex(player[0],0,tmpCity);
                
                     stuff
                
                
                     city[0]=tmpCity
                     cityPop=city[0].population;
                where you end up with cityPop being the population of player[0]'s 0th (=1st in ordinary language) city. This is what builtins are really useful for: they let you access the current values of their 'members', all those '.XXX's that are listed in the SLIC Built-in variable types document. (BTW, it's a pity there's never going to be another patch because we could sure use a few more, like "city.production" and "player.government".)

                But, after all that, you're not using "city[0]" to access a member of the builtin city array, so you don't really need it.

                As well as what Martin and Locutus said, you need to reverse the order of two of the above lines so they become:

                Code:
                for(i=0; i< player[0].cities; i=i+1) { 		
                    GetCityByIndex(player[0], i, tmpCity);// Scroll over all cities						
                    if(CityHasBuilding(tmpCity, "IMPROVE_NUCLEAR_PLANT")){		// if city has Nuclear Plant
                     randomnum = random(300);						// there is a 300 Chance. 					
                     if(randomnum == 0 && !HasAdvance(player[0], ID_ADVANCE_FUSION)){ //and player does not own fusion
                	     Event: NukeCity(tmpCity, player[0]); 			// a nuclear explosion (nuke).
                	     message(tmpplayer, 'NuclearBoom');
                	    }	
                	}
                }
                But, again, I'd be surprised if that works. You're trying to get a player to nuke his own city and I don't know if the game will allow that. It will be interesting to see if you can.

                Comment


                • #9
                  If you want that a message is not sent to AI players than I would but the message command into an if condition:

                  Code:
                  if(randomnum == 0	//if randomnum equal to 0 
                  && !HasAdvance(player[0], ID_ADVANCE_FUSION)){	// and players doenst have fusion 
                  Event: NukeCity(city[0], player[0]);		// a nuclear explosion (nuke).
                  if(IsHumanPlayer(player[0])){
                  message(player[0], 'NuclearBoom');	// and a warning message will appear
                  }
                  }
                  For the message box I would use


                  If you code it like this:

                  Code:
                  Alertbox 'NuclearBoom' {
                  	Show();
                  	Title(ID_NUCLEAR_BOOM_TITLE);
                  	if (IsHumanPlayer(player[0])) {
                  		Text(ID_NUCLEAR_BOOM_US);
                  		Eyepoint(city[0]);
                  	}else {
                  		Text (ID_NUCLEAR_BOOM_THEM};
                  	}
                  }
                  Than you want to sent this message to more than one player, than it would be better to sent it to all player, use the MessageAll instead of Message in the main event handler, of course without the if condition around. And it has only the message_id as argument.

                  Then I would modify the code like this:

                  Code:
                  Alertbox 'NuclearBoom' {
                  	Show();
                  	Title(ID_NUCLEAR_BOOM_TITLE);
                  	if (g.player == player[0]) {
                  		Text(ID_NUCLEAR_BOOM_US);
                  		Eyepoint(city[0]);
                  	}else {
                  		Text (ID_NUCLEAR_BOOM_THEM};
                  	}
                  }
                  In this case the message boom us go to the victim, boom them goes then to every other player. In your code boom us went to all human player in a game (In SP only one persion in MP more than human players). In your version the message went only to the nuked player. If it is a human player than nuked us, if an AI player than nuked them.

                  BTW Peter it wouldn't surprise me if it work, you can do in slic very interesting things if you don't care, like moving units on enemy units, or make slavers to enslave themthelves.

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

                  Comment


                  • #10
                    If its not possible to nuke yourself, then simulate it by replacing:
                    Code:
                    Event: NukeCity(tmpCity, player[0]);
                    with the effects of the nuke:
                    1. Dead people...
                    Code:
                    city[0] = tmpCity;
                    AddPops(tmpCity, city[0].population/-3);
                    2. Visuals...
                    Code:
                    AddEffect(city[0].location, “SPECEFFECT_NUKE”, “SOUND_ID_NUCLEAR_ATTACK”);
                    3. Dead Tiles around the city...
                    Code:
                    int_t  rnd;
                    rnd = random(5);
                    int_t k;
                    location_t DeadLoc;
                    for(k=0; k < rnd; k = k + 1){
                         GetRandomNeighbor(city[0].location, DeadLoc);
                         terraform(DeadLoc, TerrainDB(TERRAIN_DEAD));
                    }
                    4. KillUnits in the city...
                    Code:
                    int_t j;
                    unit_t  tmpUnit;
                    j = GetUnitsAtLocation (city[0].location);
                    for(k = 0; k < j; k = k + 1){
                         GetUnitFromCell(city[0].location, k, tmpunit);
                           Event:KillUnit(tmpunit, 0, -1);
                    }
                    Not the easiest way, but still...
                    Concrete, Abstract, or Squoingy?
                    "I don't believe in giving scripting languages because the only additional power they give users is the power to create bugs." - Mike Breitkreutz, Firaxis

                    Comment


                    • #11
                      Or let the Barbs do the nuking
                      Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

                      Comment


                      • #12
                        or that.
                        Concrete, Abstract, or Squoingy?
                        "I don't believe in giving scripting languages because the only additional power they give users is the power to create bugs." - Mike Breitkreutz, Firaxis

                        Comment


                        • #13
                          I am kind of surprise because i thought the slic would read the code as a whole. But now i relize that it cross the code as a wave. Something like: it reads the line 1 first, then line 2, then line 3 ... (I hope you guys understood me)

                          Originally posted by Peter Triggs
                          You have a "player[0]" and "value[0]" (= the game turn) to play with. These are the only builtin variables that will automatically have values when this handler triggers. So when you write "tmpcity = city[0];" as you did above, you'll get a "Variable 0 Out of Bounds" error: there is no city[0] in this context.
                          ...
                          As well as what Martin and Locutus said, you need to reverse the order of two of the above lines so they become:
                          I thought those the game just read the integer. And this integer was going to become something in the game. So its value and meaning was absolute and got shape as the slic was been written but was equal through out all code. (I hope you got that too)

                          But, after all that, you're not using "city[0]" to access a member of the builtin city array, so you don't really need it.
                          Actually when i made a first draft of the code i used tmpcity all the time i just change after i saw the message cod could not figure out what that was. It just know what city[0] means. So i changed this integer name.

                          Nice words about the handler having a buit in interger. I did never think about befor. I thougth they were only read whent the event was being used as functions

                          But, again, I'd be surprised if that works. You're trying to get a player to nuke his own city and I don't know if the game will allow that. It will be interesting to see if you can.
                          I thought the game itself was going to nuke me. Dont you think tat following that point of view this fuction was never going to work since it always meant the civ would always nuke itself.

                          Martin, I think just the human player is worthy have this message. Why would i send to the others. Ooop it just hit me while i was writing. Are you thinking in a multiplayer? So it is a good idea.

                          I will test it today. using all of you guys advices. I'll keep you informed. Any problem i can use IW codes (but it wasnt going to be my code at the end
                          "Kill a man and you are a murder.
                          Kill thousands and you are a conquer.
                          Kill all and you are a God!"
                          -Jean Rostand

                          Comment


                          • #14
                            Originally posted by Pedrunn
                            I thought the game itself was going to nuke me. Dont you think tat following that point of view this fuction was never going to work since it always meant the civ would always nuke itself.
                            You used player[0] as the player who will nuke the city. So you will nuke yourself. As the documention says NukeCity is the actual event that nukes a city, it is highly possible that there are no legality checks on this event, so it will work I think otherwise replace player[0] by 0, so that the Barbarians will always nuke the city.

                            Originally posted by Pedrunn
                            Martin, I think just the human player is worthy have this message. Why would i send to the others. Ooop it just hit me while i was writing. Are you thinking in a multiplayer? So it is a good idea.
                            Of course in MP (just notice I forgot a word in the post above). It is easier to send the message to all (I think the message won't send to the AI anyway), than to code it so that it will only sent to all human players.

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

                            Comment


                            • #15
                              I see. I though the int_t player at the vent NukeCity was the player who is going to be hit and not the one hitting.
                              I will fix that.

                              Thanks again
                              "Kill a man and you are a murder.
                              Kill thousands and you are a conquer.
                              Kill all and you are a God!"
                              -Jean Rostand

                              Comment

                              Working...
                              X