Announcement

Collapse
No announcement yet.

Increasing Bombardment Range

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

  • Increasing Bombardment Range

    I found this in: ctp2_code\gs\gameobj\unitdata.cpp

    Code:
    sint32 UnitData::CanBombard(CellUnitList &defender) const 
    
    {
       const UnitRecord *rec = g_theUnitDB->Get(m_type);
       double r = rec->GetBombardRange() + 0.5;
       double rsq = r * r;
    
       MapPoint dpos;
       defender.GetPos(dpos);
       if(GetDistance(dpos, m_pos, (sint32)r) > rsq)
    	   return FALSE;
    
       if (rec->GetCanBombardLand()) 
          if (defender.IsAtLeastOneMoveLand())
             return TRUE; 
    
       if (rec->GetCanBombardWater()) 
          if (defender.IsAtLeastOneMoveWater() || defender.IsAtLeastOneMoveShallowWater())
             return TRUE; 
    
       if (rec->GetCanBombardAir()) 
          if (defender.IsAtLeastOneMoveAir())
             return TRUE; 
    
       if (rec->GetCanBombardSpace()) 
          if (defender.IsAtLeastOneMoveSpace())
             return TRUE; 
    
       if (rec->GetCanBombardMountain()) 
          if (defender.IsAtLeastOneMoveMountain())
             return TRUE; 
    
       return FALSE; 
    }
    
    sint32 UnitData::CanCounterBombard(CellUnitList &defender) const 
    {
       if (g_theUnitDB->Get(m_type)->GetCanCounterBombard()) { 
          return CanBombard(defender); 
       } else { 
          return FALSE; 
       }
    }
    
    sint32 UnitData::CanActivelyDefend(CellUnitList &attacker) const
    {
    	const UnitRecord *rec = g_theUnitDB->Get(m_type);
    	if(rec->GetActiveDefenseRange() <= 0)
    		return 0;
    
    	BOOL movesMatch = FALSE;
    	if(attacker.IsAtLeastOneMoveLand() &&  rec->GetDefendLand())
    		movesMatch = 0;
    
    	if(attacker.IsAtLeastOneMoveWater() && rec->GetDefendWater())
    		movesMatch = TRUE;
    
    	if(attacker.IsAtLeastOneMoveAir() && rec->GetDefendAir())
    		movesMatch = TRUE;
    
    	if(attacker.IsAtLeastOneMoveSpace() && rec->GetDefendSpace())
    		movesMatch = TRUE;
    
    	if(attacker.IsAtLeastOneMoveMountain() && rec->GetDefendMountain())
    		movesMatch = TRUE;
    
    	if(movesMatch) {
    		if(rec->GetActiveDefenseOnlyWhenCarryingEnablers()) {
    			sint32 numEnablers = 0;
    			sint32 i;
    			for(i = 0; i < m_cargo_list->Num(); i++) {
    				if(m_cargo_list->Access(i).GetDBRec()->GetEnableCarrierDefenses())
    					numEnablers++;
    			}
    			return numEnablers;
    		}
    		return 1;
    	}
    	return 0;
    }
    
    double UnitData::GetAttack(const UnitRecord *rec, const Unit defender) const
    {
    	MapPoint dpos;
    	double attack, baseattack;
    	const UnitRecord *defrec = defender.GetDBRec();
    
    	defender.GetPos(dpos);
    	attack = baseattack = rec->GetAttack();
    
    	if(!(rec->GetCanAttack() & defender.GetDBRec()->GetMovementType())) {
    		return 0;
    	}
    
    	if(defrec->GetWoodenShip()) {
    		attack += baseattack * rec->GetAttackWoodenShipBonus();
    	}
    
    	if(g_theWorld->GetCell(dpos)->GetCity().m_id != (0)) {
    		attack += baseattack * rec->GetAttackCityBonus();
    	}
    
    	if(defrec->GetIsSubmarine()) {
    		attack += baseattack * rec->GetAttackBonusSubmarine();
    	}
    
    	return attack;
    }
    
    void UnitData::Bombard(const UnitRecord *rec, Unit defender,
    					   BOOL isCounterBombardment)
    {
    	double prob;
    	sint32 f = (sint32)(rec->GetFirepower() /  
    		g_theUnitDB->Get(defender.GetType())->GetArmor()); 
    	sint32 n;
    	bool canBombard = rec->GetBombRounds(n);			
    	Assert(canBombard);
    	if(!canBombard)
    		n = 0;
    
    	double hp = defender.GetHP(); 
    	sint32 p;
    	sint32 i; 
    
    	g_slicEngine->RunCounterBombardmentTriggers(defender, Unit(m_id));
    
    	double defenseStrength = defender.GetDefense(Unit(m_id));
    	double attack = rec->GetZBRangeAttack();
    
    	prob = attack / (attack + defenseStrength);
    	p = sint32(prob * 100);
    
    	double dmr = 1.0/defender.GetHPModifier(); 
    	if (IsVeteran()) 
    		p += sint32(double(p) * g_theConstDB->GetVetCoef()); 
    	
    	for (i=0; iNext(100) < p) { 
    			hp -= f * dmr; 
    		} 
    	}
    	defender.SetHP(hp); 
    	if(isCounterBombardment) {
    		g_slicEngine->RunCounterBombardmentTriggers(Unit(m_id), defender);
    	} else {
    		g_slicEngine->RunBombardmentTriggers(Unit(m_id), defender);
    	}
    }
     
    void UnitData::BombardOneRound(const UnitRecord *rec, Unit &defender, 
                                   double dbonus, 
                                   double dmr)
    {
       sint32 p = rec->GetProbOfBombHit();
       sint32 f = rec->GetZBRangeAttack(); 
       double hp = defender.GetHP(); 
    
       if (IsVeteran()) 
          p += sint32(double(p) * g_theConstDB->GetVetCoef()); 
    
    
       p  = int (p *(1.0 + dbonus)); 
    
       if (g_rand->Next(100) < p) { 
             hp -= f * dmr; 
       } 
       defender.SetHP(hp); 
    }
    
    BOOL UnitData::CanBombardType(const Unit & defender) const
    {
    	const UnitRecord *rec = g_theUnitDB->Get(m_type); 
    
    	if (rec->GetCanBombardLand() || rec->GetDefendLand()) {
    		if (defender.GetMovementTypeLand()) {
    			return TRUE;
    		}
    	}
    	
    	if (rec->GetCanBombardWater() || rec->GetDefendWater()) {
    		if (defender.GetMovementTypeSea() || defender.GetMovementTypeShallowWater()) {
    			return TRUE;
    		}
    	}
    	
    	if (rec->GetCanBombardAir() || rec->GetDefendAir()) {
    		if (defender.GetMovementTypeAir()) {
    			return TRUE; 
    		}
    	}
    	
    	if (rec->GetCanBombardSpace() || rec->GetDefendSpace()) {
    		if (defender.GetMovementTypeSpace()){
    			return TRUE;
    		}
    	}
    	
    	if (rec->GetCanBombardMountain() || rec->GetDefendMountain()) {
    		if (defender.GetMovementTypeMountain()) {
    			return TRUE;
    		}
    	}
    	return FALSE;
    }
    
    BOOL UnitData::Bombard(CellUnitList &defender, BOOL isCounterBombardment) 
    { 
    	const UnitRecord *rec = g_theUnitDB->Get(m_type); 
    	sint32 i, j, r; 
    
    	Assert(0 < defender.Num()); 
    	r = g_rand->Next(defender.Num()); 
    
    	for (i=r, j=0; 
    		 j < defender.Num(); 
    		 i = ((i + 1) % defender.Num()), j++) { 
    
    		if(!(defender[i].GetVisibility() & (1 << m_owner)) && !g_theWorld->GetCity(defender[i].RetPos()).IsValid())
    			continue;
    
    		if (CanBombardType(defender[i]) || rec->GetSingleUse())
    		{
    			Bombard(rec, defender[i], isCounterBombardment);
    			return TRUE;
    		}
    	}
    	return FALSE;
    }


    I'm not a coder but I'm trying to learn, but I cant see where in this code that it only makes bombardment one-square away. Can anyone see where it says that or what the problem is?
    Last edited by Ekmek; October 1, 2004, 17:24.
    Formerly known as "E" on Apolyton

    See me at Civfanatics.com

  • #2
    I think this is it:

    Code:
     ORDER_RESULT ArmyData::Bombard(const MapPoint &orderPoint)
    {
    
    	MapPoint point = orderPoint;
    
    	static CellUnitList defender;
    	defender.Clear();
    	g_theWorld->GetArmy(point, defender);
    	sint32 i;
    	
    	BOOL isSpaceBombard = FALSE;
    	if(point == m_pos) {
    		return ORDER_RESULT_ILLEGAL;
    	} else {
    		if([b]!point.IsNextTo(m_pos)[/b]) {
    			return ORDER_RESULT_ILLEGAL;
    		}
    	}
    When they moved from Civ:CTP to CTP2 they put in a "fire and forget" feature which lets you select a
    target and let your army move towards it on its own in order to carry out it's given order. If you want to
    re-instate bombarding from a distance you'll have to keep an eye on this.

    Comment


    • #3
      If you remove that line which checks if the point is adjacent, it still won't help much. You can remove that and add ranged bombard. However, then a unit ordered to do ranged bombardment will still want to move adjacent to its target and attack then, which is why its also neccessary to eliminate that feauture to reinstate ranged bombardment.
      Solver, WePlayCiv Co-Administrator
      Contact: solver-at-weplayciv-dot-com
      I can kill you whenever I please... but not today. - The Cigarette Smoking Man

      Comment


      • #4
        I was looking in Units.txt and Orders.txt last night and there is a flag which looks like it limits the range of actions. The values are all set to 0 or 1 e.g. reform city is 0 and bombard is 1 so this might be where the limit comes from.
        ·Circuit·Boi·wannabe·
        "Evil reptilian kitten-eater from another planet."
        Call to Power 2 Source Code Project 2005.06.28 Apolyton Edition

        Comment


        • #5
          Originally posted by Peter Triggs
          I think this is it:

          Code:
           ORDER_RESULT ArmyData::Bombard(const MapPoint &orderPoint)
          {
          
          	MapPoint point = orderPoint;
          
          	static CellUnitList defender;
          	defender.Clear();
          	g_theWorld->GetArmy(point, defender);
          	sint32 i;
          	
          	BOOL isSpaceBombard = FALSE;
          	if(point == m_pos) {
          		return ORDER_RESULT_ILLEGAL;
          	} else {
          		if([b]!point.IsNextTo(m_pos)[/b]) {
          			return ORDER_RESULT_ILLEGAL;
          		}
          	}
          When they moved from Civ:CTP to CTP2 they put in a "fire and forget" feature which lets you select a
          target and let your army move towards it on its own in order to carry out it's given order. If you want to
          re-instate bombarding from a distance you'll have to keep an eye on this.
          Ok this is where my skills are obviously weak. I'm thinking I need to make the defender's point less than or equal to bombard range value from attacker's point in order to return a true statement and if point is greater tha bombard range than it should return false.

          but i don't see code that identifies where the attacker is. Where did this code come from? And I don't see where the code links to bombard effects, firepower (?) and chance of success.


          But which file is this in? I'm thinking I can get the data from the nuke and target order to see how to put bombard range in.
          Last edited by Ekmek; October 1, 2004, 17:14.
          Formerly known as "E" on Apolyton

          See me at Civfanatics.com

          Comment


          • #6
            Originally posted by E
            Ok this is where my skills are obviously weak. I'm thinking I need to make the defender's point less than or equal to bombard range value from attacker's point in order to return a true statement and if point is greater tha bombard range than it should return false.

            but i don't see code that identifies where the attacker is. Where did this code come from? And I don't see where the code links to bombard effects, firepower (?) and chance of success.

            But which file is this in? I'm thinking I can get the data from the nuke and target order to see how to put bombard range in.
            I'll try to walk you through it.

            First thing to note is that you should use [code][/code] tags to surround code to preserve the indenting when you post it here at 'Poly.

            Code:
            ORDER_RESULT ArmyData::Bombard(const MapPoint &orderPoint)
            This first line says that this code is defining a Bombard method for the class ArmyData. Thus, you can find this code in ArmyData.cpp (that, together with ArmyData.h define the ArmyData class). Each instance of this class represents data about a single army, and also carries these methods to perform actions related to the army (like bombarding),

            This function takes just one argument, orderPoint, which is of type MapPoint. This represents the position on the map being bombarded.

            Code:
            {
            	MapPoint point = orderPoint;
            The code immediately defines a local variable called point and copies the position being bombarded into it.
            Code:
            	static CellUnitList defender;
            	defender.Clear();
            	g_theWorld->GetArmy(point, defender);
            Now the code fetches any army which might exist at this location.
            Code:
            	sint32 i;
            	
            	BOOL isSpaceBombard = FALSE;
            the isSpaceBombard variable is probably a leftover from CTP space bombers.
            Code:
            	if(point == m_pos) {
            		return ORDER_RESULT_ILLEGAL;
            The first check here tests whether the army is trying to bombard itself - the variable m_pos is a member variable of the ArmyData class which stores the location of this army, you can see it defined in ArmyData.h. If the location of this army is the same as the location being bombarded, then give up and say the order is illegal.
            Code:
            	} else {
            		if(!point.IsNextTo(m_pos)) {
            			return ORDER_RESULT_ILLEGAL;
            		}
            	}
            Otherwise, this next check uses the IsNextTo method of MapPoint to test whether the point being bombarded is next to the position of this army. If it isn't, the order is declared illegal.

            And so forth...

            Comment


            • #7
              Interestingly, the code you have pasted from unitdata.cpp does appear to allow for longer ranged bombarding...

              Comment


              • #8
                Code:
                sint32 UnitData::CanBombard(CellUnitList &defender) const 
                
                {
                const UnitRecord *rec = g_theUnitDB->Get(m_type);
                double r = rec->GetBombardRange() + 0.5;
                double rsq = r * r;
                
                MapPoint dpos;
                defender.GetPos(dpos);
                if(GetDistance(dpos, m_pos, (sint32)r) > rsq)
                return FALSE;
                
                if (rec->GetCanBombardLand()) 
                if (defender.IsAtLeastOneMoveLand())
                return TRUE;
                I see that (defender.IsAtLeastOneMoveLand())

                also restricts it to one movement of land. I'm thinking I should change this to GetbombardRnage in order to have a value. Or I probably need to edit this function to something like "IsWithinRange" anybody see where GetBombardRange is?
                Formerly known as "E" on Apolyton

                See me at Civfanatics.com

                Comment


                • #9
                  Thanks J,

                  I guess my next post crossed with yours. And I think you saw the same thingI did where it appears to do long range bombard.

                  Again, THank you very much for your walkthrough, it helped more than the C book I'm flipping through
                  Formerly known as "E" on Apolyton

                  See me at Civfanatics.com

                  Comment


                  • #10
                    Can't remember when I saw that previously, but even the bombardrange unit flag was checked for in the code. It's the IsNextTo function call that overrides ranged bombard orders, IIRC.
                    Solver, WePlayCiv Co-Administrator
                    Contact: solver-at-weplayciv-dot-com
                    I can kill you whenever I please... but not today. - The Cigarette Smoking Man

                    Comment


                    • #11
                      Solver,

                      I think you might have ran into it during your (aborted) aircombat code...


                      off to find "IsNextTo"
                      Formerly known as "E" on Apolyton

                      See me at Civfanatics.com

                      Comment


                      • #12
                        Yes, that it was probably. I was researching the possibility of ranged bombardment assignment, and did notice that the bombardment code is pretty much screwed up. It seemed stupid how it does check for bombard range, yet orders are illegal for bombardment of non-adjacent targets.
                        Solver, WePlayCiv Co-Administrator
                        Contact: solver-at-weplayciv-dot-com
                        I can kill you whenever I please... but not today. - The Cigarette Smoking Man

                        Comment


                        • #13
                          Hmm, do we have the source code online somewhere on a CVS? I currently have no access to the source, so I can't verify my memories...
                          Solver, WePlayCiv Co-Administrator
                          Contact: solver-at-weplayciv-dot-com
                          I can kill you whenever I please... but not today. - The Cigarette Smoking Man

                          Comment


                          • #14
                            from \ctp2_code\gs\world\mappoint.cpp

                            Code:
                            BOOL MapPoint::IsNextTo(const MapPoint &neighbor) const 
                            
                            {
                            	static MapPoint tmp;
                                
                              
                            
                                
                                if(GetNeighborPosition(NORTH,tmp))
                            	   if (neighbor == tmp) return TRUE; 
                            
                            	if(GetNeighborPosition(NORTHWEST,tmp))
                            		if (neighbor == tmp) return TRUE; 
                            
                                if(GetNeighborPosition(NORTHEAST,tmp))
                            		if (neighbor == tmp) return TRUE; 
                            
                                if(GetNeighborPosition(SOUTH,tmp))
                            		if (neighbor == tmp) return TRUE; 
                            
                                if(GetNeighborPosition(SOUTHWEST,tmp))
                            		if (neighbor == tmp) return TRUE; 
                            
                                if(GetNeighborPosition(SOUTHEAST,tmp))
                            		if (neighbor == tmp) return TRUE; 
                            
                                if(GetNeighborPosition(WEST,tmp))
                            		if (neighbor == tmp) return TRUE; 
                            
                                if(GetNeighborPosition(EAST,tmp))
                            		if (neighbor == tmp) return TRUE; 
                            
                                return FALSE; 
                            }
                            
                            
                            struct ScreenPoint
                            {
                            	ScreenPoint(const MapPoint &mp)
                            	{
                            		x = 2 * mp.x + mp.y;
                            		y = mp.y;
                            		if (x >= 2 * g_mp_size.x)
                            			x -= 2 * g_mp_size.x;
                            	}
                            	sint32 x, y;
                            };
                            
                            
                            
                            
                            static sint32 WrapDelta(sint32 delta, sint32 size)
                            {
                            	if (delta > 0)
                            	{
                            		if (2*delta > size)
                            			delta -= size;
                            	}
                            	else
                            	{
                            		if (-2*delta > size)
                            			delta += size;
                            	}
                            	return delta;
                            }

                            I'm thinking if I add a math function that involves less than or equal bombard range, I can make a WithinRange function that will restore bombard range...
                            Last edited by Ekmek; October 1, 2004, 17:54.
                            Formerly known as "E" on Apolyton

                            See me at Civfanatics.com

                            Comment


                            • #15
                              Originally posted by Solver
                              Hmm, do we have the source code online somewhere on a CVS? I currently have no access to the source, so I can't verify my memories...
                              I dont think its on a CVS, I just downloaded it and went through it agin. If you need specific files I can post them.
                              Formerly known as "E" on Apolyton

                              See me at Civfanatics.com

                              Comment

                              Working...
                              X