Announcement

Collapse
No announcement yet.

PROJECT: Good Specific Terrain Improvements

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

  • #16
    The attempt before was better, now you have restricted every tile improvements to goods and actual you just want to restrict those tile improvements that have at least one. That means that if the number of IsRestrictedToGood is greater then 0, that means IsRestrictedToGood is present in the database record, you want to continue with your code, that checks whether the right good is at the location. So you want to continue with your code, and if your for loop does not return true means that the right good is not present at the given location and therefore you cannot build the tile improvement at the given location, therefore the function must then and only then return false.

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

    Comment


    • #17
      Martin et al,

      I guess my logic is whats messing it up...

      Should I put the can't build on FIRST as a check and then an 'else' statement to provide for the next check. Or is there something else I should use an 'else-if' or a '&&' ????



      But here is another try going back to my original code.

      Code:
      for(i = 0; i < rec->GetNumCantBuildOn(); i++) {
      	if(rec->GetCantBuildOnIndex(i) == cell->GetTerrain()) {
      				return false;
      			}
      		}
      sint32 good;
      
      if(g_theWorld->GetGood(good)) {
      	m_result.m_int = -1;
      		} else {
      			m_result.m_int = good;}
      elseif(i = 0; i < rec->GetNumIsRestrictedToGood(); i++) {
      	if(rec->GetIsRestrictedToGoodIndex(i) == GetGood(good) ) {
      		return true; 
      	}
      }		
      	}
      	return true;
      }
      Formerly known as "E" on Apolyton

      See me at Civfanatics.com

      Comment


      • #18
        Martin and J,

        Is this any closer?

        Code:
        for(i = 0; i < rec->GetNumCantBuildOn(); i++) {
        	if(rec->GetCantBuildOnIndex(i) == cell->GetTerrain()) {
        				return false;
        			}
        		}
        sint32 good;
        
        if(g_theWorld->GetGood(good)) {
        	m_result.m_int = -1;
        		} else {
        			m_result.m_int = good;}
        elseif(i = 0; i < rec->GetNumIsRestrictedToGood(); i++) {
        	if(rec->GetIsRestrictedToGoodIndex(i) == GetGood(good) ) {
        		return true; 
        	}
        }		
        	}
        	return true;
        }
        Formerly known as "E" on Apolyton

        See me at Civfanatics.com

        Comment


        • #19
          Not today E, I have to prepare a talk for tomorrow. So don't expect a comprehensive answer. First where does the code fragment starts. Second what does "elseif" combined with for loop syntax in the code, "elseif" is a slic token in c++ it is called "else if". Third what does this m_result.m_int slic related c++ code piece there. And fourth get the indention right so that I can see something there.

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

          Comment


          • #20
            Ok here is another shot. I thik my logic flaw was that I tried to check if you could build on a good first as opposed to checking the tile first. So I assumed that what I need ed to do was "improve" the can't build on code by adding another search function after you checked if it is restricted or not. I think my bools line up now and the logic flows...


            Code:
            		sint32 good;
            		if(cell->GetGood(good)>0 {
            			(!g_theWorld->GetGood(rec->GetGoodsIndex(good)) 
            				return true; }
            		for(i = 0; i < rec->GetNumCantBuildOn(); i++) {
            			if(rec->GetCantBuildOnIndex(i) == cell->GetTerrain()) {
            				return true;
            			}
            		}
            		if (rec->GetNumIsRestrictedToGood()&& GetGood(good)
            				return true;
            
            	return false;
            Formerly known as "E" on Apolyton

            See me at Civfanatics.com

            Comment


            • #21
              Code:
              	} else {
              		const TerrainImprovementRecord::Effect *eff;
              		eff = terrainutil_GetTerrainEffect(rec, cell->GetTerrain());
              		if(!eff)
              			return false;
              		if(!g_player[pl]->HasAdvance(eff->GetEnableAdvanceIndex()))
              			return false;
              		sint32 a;
              		for(a = 0; a < eff->GetNumObsoleteAdvance(); a++) {
              			if(g_player[pl]->HasAdvance(eff->GetObsoleteAdvanceIndex(a))) {
              				return false; }}
              		for(i = 0; i < rec->GetNumCantBuildOn(); i++) {
              			if(rec->GetCantBuildOnIndex(i) == cell->GetTerrain()) {
              				return false; }}
              		[b]for(i = 0; i < rec->GetNumIsRestrictedToGood(); i++) {
              			if(rec->GetIsRestrictedToGoodIndex(i) == cell->GetGood()) {
              				return true; }}[/b]
              	}
                              return true;
              }
              Better start from here again, of course afterwards you got the indention right . Now you have to make sure that your new code is executed if and only if the tile improvement is restricted at least to one good. You should know how to get this number, as you use it in your new code. And to achieve this if and only if condition you surround your new code by braces, one open brace before '{' and one closing brace '{' afterwards. And before the open brace you put an if with the according condition.

              And before the for loop you have to retrieve the good's database index that you can find on the terrain, and to do this you use the GetGood function from the world object. And in slic you have an instance how it is used:

              Code:
              SlicFunc.cpp
              SFN_ERROR Slic_HasGood::Call(SlicArgList *args)
              {	
              	if(args->m_numArgs != 1)
              		return SFN_ERROR_NUM_ARGS;
              	MapPoint pos;
              	if(!args->GetPos(0, pos))
              		return SFN_ERROR_TYPE_ARGS;
              	sint32 good;
              	if(!g_theWorld->GetGood(pos, good)) {
              		m_result.m_int = -1;
              	} else {
              		m_result.m_int = good;
              	}
              	
              	return SFN_ERROR_OK; 
              }
              The GetGood function gets two arguments, a map point and an integer, both arguments are passed by refference not by value. That means the good variable used inside the function is the same instead of a copy, like outside the function, that means the function can assign a value to the good variable that can be used outside, quasi a second return value.

              So first thing you have to do here is to retrieve the good's index. Maybe you should also check the return value of the GetGood function and if it is false you should leave the function with a return false.

              And finally once you have done the for loop in your new and it didn't return true, the function must return false, but only if it executed your new code.

              -Martin
              Last edited by Martin Gühmann; February 12, 2005, 12:10.
              Civ2 military advisor: "No complaints, Sir!"

              Comment


              • #22
                Notes on some code I need to look at...

                Code:
                sint32 Cell::GetGoodsIndex(sint32 &val) const
                {
                    val = (m_env & k_MASK_ENV_GOOD);
                    if (val == 0) {
                        return FALSE;
                	} else {
                		val >>= k_SHIFT_ENV_GOOD;
                		val--;
                		while(val >= 0 && 
                			  (g_theTerrainDB->Get(m_terrain_type)->GetNumResources() <= val)) {
                			val--;
                		}
                		if(val < 0)
                			return FALSE;
                		return TRUE;
                    }
                }
                Code:
                BOOL World::GetGood(const MapPoint &pos, sint32 &good) const
                {
                	
                    sint32 i; 
                    Cell *c = GetCell(pos);
                	
                    if (c->GetGoodsIndex(i)) { 
                        good= g_theTerrainDB->Get(c->m_terrain_type)->GetResourcesIndex(i);
                		return TRUE;
                    } else { 
                        return FALSE; 
                    }
                }
                Formerly known as "E" on Apolyton

                See me at Civfanatics.com

                Comment


                • #23
                  The first function returns TRUE or FALSE whether the Cell has a good or not. The val argument is filled with a number between -1 and 3, -1 if the location has no good, 0 if the location has the good that is refferenced by the first Ressource entry in the according database record of the terrain. And respectively for the goods referenced by the higher array members.

                  The second function retrieves the good's database index of the good that is found on the given position. It returns TRUE if there is a good on the given location otherwise FALSE. The argument good is filled with the found good's database index.

                  The second function is the function you have to use, since you are interested in the good's database index and not in the good's terrain member index.

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

                  Comment


                  • #24
                    from terrainutil.cpp terrainutil_CanPlayerBuildAt
                    Code:
                    [b]		sint32 good;
                    		if(cell->GetGood(good)>0 {
                    			(g_theWorld->GetGood(good)&& g_theWorld->GetGood(rec->GetIndex(good))
                    		} else {
                    			return false; 
                    		}
                    		Cell *c = GetCell(pos);
                    		if (c->GetGoodsIndex(good)) { 
                    			good= g_theTerrainDB->Get(c->m_terrain_type)->GetResourcesIndex(good);
                    				return true;
                    		} else { 
                    				return false; 
                    		}
                    		if (i = 0; i < rec->GetNumIsRestrictedToGood(); i++) {
                    			if(rec->GetIsRestrictedToGoodIndex(i) == GetGoodsIndex(good)) {
                    				return true; 
                    			}
                    		}[/b]	
                    		for(i = 0; i < rec->GetNumCantBuildOn(); i++) {
                    			if(rec->GetCantBuildOnIndex(i) [b]![/b]= cell->GetTerrain()) {
                    				return [b]true[/b];
                    			}
                    		}
                    	}
                    	return false;
                    }
                    In BOLD is my code as usual.

                    1) I used the GetGood function to identify if the spot the player is trying to build has a good or not. I have to admit here that its kind of fuzzy how the system checks here, I really don't "see" in the code how the system knows which tilethe player is building on, is that an event or something?

                    2) I created a variable good and if the tilehas a good it returns its index value, if not false. This is another C++ question, I don't have the braces around the other code will the progran stop running at the first false or check all conditions?

                    3)In the GetGoodIndex part if it returns true for a value good, will it stop runing the program or run to the next function? Should I remove the else {return false} and make it that if it returns true it does the nex function?

                    4) finally I have it check for the value in GetRestiictedtoGood value and if it equals the same as good value its true. This is similar to my last code so I think thats close (my only dount is on the good variable)

                    5) Finally, if the IsRestrictedtoGood flag is not there how do I know it will still run the program?

                    Sorry for the questions this time but I'm trying to get a bit more of an understanding...
                    Last edited by Ekmek; February 14, 2005, 00:52.
                    Formerly known as "E" on Apolyton

                    See me at Civfanatics.com

                    Comment


                    • #25
                      Well E the code is something else then I told you...

                      Originally posted by E
                      1) I used the GetGood function to identify if the spot the player is trying to build has a good or not. I have to admit here that its kind of fuzzy how the system checks here, I really don't "see" in the code how the system knows which tilethe player is building on, is that an event or something?
                      That's simple check the parameter list of the function you are modifying, it is the parameter const MapPoint &pos. And you don't need to understand the logic inside the function you just need to know what you can do with these functions. And actual I already told you that you only need the GetGood function from the world and no GetGoodsIndex function, this function is used of the GetGood function, there is no need to mess around with it.

                      Originally posted by E
                      2) I created a variable good and if the tilehas a good it returns its index value, if not false. This is another C++ question, I don't have the braces around the other code will the progran stop running at the first false or check all conditions?
                      That's stupid the function should return true if the player is allowed to build the given tarrain improvement at the given place and false if he isn't allowed to do so. There is no room for an index there. However it doesn't return there anything because it doesn't has a return statement and the final colon is missing. And this first if-else pair causes the function to return false if there is no good at the place always.

                      Originally posted by E
                      3)In the GetGoodIndex part if it returns true for a value good, will it stop runing the program or run to the next function? Should I remove the else {return false} and make it that if it returns true it does the nex function?
                      You should remove this GetGoodsIndex function alltogether, you don't need it at all as I said above.

                      Originally posted by E
                      4) finally I have it check for the value in GetRestiictedtoGood value and if it equals the same as good value its true. This is similar to my last code so I think thats close (my only dount is on the good variable)
                      I still have no idea what you want with this if-for-loop hybrid synthax. That doesn't do anything it even doesn't compile. However once you changed this if-for-hybrid stuff into a real for loop you have to compare each RestrictedToGood index to the good index you have retrieved before and stored in the good variable, don't use this GetGoodsIndex function, it doesn't even compile since it is a member of Cell.

                      Originally posted by E
                      5) Finally, if the IsRestrictedtoGood flag is not there how do I know it will still run the program?
                      That is a pretty good question and if I remember correctly the answer is in this thread, but here again: You have this GetNumIsRestrictedToGood function. This function returns the number of goods to that your improvement is restricted. For a tile improvement without any restrictions it returns 0. So all you have to do is to use an

                      if(){
                      }

                      statement. If this function I refered above returns a number bigger than 0 then your new code is executed. otherwise it isn't executed. And of course leave the original code as it is, don't mess with this around and of course you new code is insereted after the original code.

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

                      Comment


                      • #26
                        from terrainutil.cpp terrainutil_CanPlayerBuildAt
                        Code:
                        [b]		sint32 good;
                        		if(cell->GetGood(good)>0 {
                        			(g_theWorld->GetGood(good)&& g_theWorld->GetGood(rec->GetIndex(good))
                        		} else {
                        			return false; 
                        		}
                        	
                        		
                        		if (i = 0; i < rec->GetNumIsRestrictedToGood(); i++) {
                        			if(rec->GetIsRestrictedToGoodIndex(i) == GetGood(good)) {
                        				return true; 
                        			}
                        		}[/b]	
                        		for(i = 0; i < rec->GetNumCantBuildOn(); i++) {
                        			if(rec->GetCantBuildOnIndex(i) [b]![/b]= cell->GetTerrain()) {
                        				return [b]true[/b];
                        			}
                        		}
                        	}
                        	return false;
                        }
                        I have to re-look this but I'll make quick changes for now.
                        Formerly known as "E" on Apolyton

                        See me at Civfanatics.com

                        Comment


                        • #27
                          Code:
                          	} else {
                          		
                          		const TerrainImprovementRecord::Effect *eff;
                          		eff = terrainutil_GetTerrainEffect(rec, cell->GetTerrain());
                          		if(!eff)
                          			return false;
                          		
                          		if(!g_player[pl]->HasAdvance(eff->GetEnableAdvanceIndex()))
                          			return false;
                          		
                          		sint32 a;
                          		for(a = 0; a < eff->GetNumObsoleteAdvance(); a++) {
                          			if(g_player[pl]->HasAdvance(eff->GetObsoleteAdvanceIndex(a))) {
                          				return false;
                          			}
                          		}
                          
                          		sint32 good;
                          		if (g_theWorld->GetGood(good)) [b][i]{ 
                          			good= g_theTerrainDB->Get(c->m_terrain_type)->GetResourcesIndex(good);
                          				return true;
                          		} else { 
                          				return false; 
                          		}[/i]
                          		for(i = 0; i < rec->GetNumIsRestrictedToGood(); i++) {
                          			if(rec->GetIsRestrictedToGood(i) == GetGood(good)) {
                          				return true; 
                          			}
                          		}[/b]	
                          		for(i = 0; i < rec->GetNumCantBuildOn(); i++) {
                          			if(rec->GetCantBuildOnIndex(i) != cell->GetTerrain()) {
                          				return true;
                          			}
                          		}
                          	}
                          	return false;
                          }
                          Martin, in Bold is mine. I've gotten rid of the Goods index, but if GetGood is more detailed than I think, then I'm guessing I have to remove the bold-italics as well and ONLY call the GetGood. I think this is what you said but I'm just checking first.

                          I also added the "for" loop, but I'm a little stumped on the good versus no good code. I think I may still have the problem of no-good means you cant build at all. Should I add an "else" in here or is there something else I need to add?
                          Formerly known as "E" on Apolyton

                          See me at Civfanatics.com

                          Comment


                          • #28
                            Originally posted by E
                            Martin, in Bold is mine.
                            That's not quite true, as it stands now this below is more or less your code.

                            Code:
                            		sint32 good;
                            		if (g_theWorld->GetGood(good)) [b][i]{ 
                            			good= g_theTerrainDB->Get(c->m_terrain_type)->GetResourcesIndex(good);
                            				return true;
                            		} else { 
                            				return false; 
                            		}[/i]
                            		for(i = 0; i < rec->GetNumIsRestrictedToGood(); i++) {
                            			if(rec->GetIsRestrictedToGood(i) == GetGood(good)) {
                            				return true; 
                            			}
                            		}[/b]	
                            		for(i = 0; i < rec->GetNumCantBuildOn(); i++) {
                            			if(rec->GetCantBuildOnIndex(i) != cell->GetTerrain()) {
                            				return true;
                            			}
                            		}
                            	}
                            	return false;
                            }
                            Originally posted by E
                            I've gotten rid of the Goods index, but if GetGood is more detailed than I think, then I'm guessing I have to remove the bold-italics as well and ONLY call the GetGood. I think this is what you said but I'm just checking first.
                            You are right the is something in that doesn't belong into it.

                            Code:
                            		sint32 good;
                            		if (g_theWorld->GetGood(good)) [b][i]{ 
                            			good= g_theTerrainDB->Get(c->m_terrain_type)->GetResourcesIndex(good);
                            				return true;
                            		} else { 
                            				return false; 
                            		}
                            First the GetGood function fills the good variable with a number the good's database index, therefore there is no need to reasign anything to it again. So get rid of the content inside of the if-block and replace it with your for-loop:

                            Code:
                            		for(i = 0; i < rec->GetNumIsRestrictedToGood(); i++) {
                            			if(rec->GetIsRestrictedToGood(i) == GetGood(good)) {
                            				return true; 
                            			}
                            		}
                            And after this for loop still inside the if-block you add an return false; because if this piece of code is reached the for-loop was executed and no match was found that means you aren't allowed to construct the tileimprovement.

                            Second the GetGood function takes two arguments, one is the position and the second one is the good.

                            And now to the last part of your code, I didn't tell you that you should modify the return values. So restore the original return vales. Inside that for loop it was return false; The final return was a return true; And please change back the equality operator from != now to == as it was.

                            For now just complete the task and then we do the final part.

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

                            Comment


                            • #29
                              Code:
                              		sint32 good;
                              		[b]if (g_theWorld->GetGood(pos, good)){
                              		for(i = 0; i < rec->GetNumIsRestrictedToGood(); i++) {
                              			if(rec->GetIsRestrictedToGood(i) == good) {
                              				return true; 
                              			}
                              		}[/b]
                              }
                              	
                              		for(i = 0; i < rec->GetNumCantBuildOn(); i++) {
                              			if(rec->GetCantBuildOnIndex(i) == cell->GetTerrain()) {
                              				return false;
                              			}
                              		}
                              	}
                              	return true;
                              }

                              just a quick correction and I'll come back to the rest of your message for the last changes
                              Last edited by Ekmek; February 27, 2005, 22:11.
                              Formerly known as "E" on Apolyton

                              See me at Civfanatics.com

                              Comment


                              • #30
                                Originally posted by E
                                just a quick correction and I'll come back to the rest of your message for the last changes
                                Yes the rest must be still incooperated. However here is still a small one: Within your for-loop you try to compare the IsRestrictedToGood members with the actual good on your tile. At first the good variable's value contains already the good index at the given terrain, therefore there is no need to call a GetGood function again. Just compare it with good.

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

                                Comment

                                Working...
                                X