another unitdef problem...

another unitdef problem...

Here is where ideas can be collected for the skirmish AI in development

Moderators: hoijui, Moderators

User avatar
Bobcatben
Posts: 120
Joined: 10 Mar 2006, 17:01

another unitdef problem...

Post by Bobcatben »

i been trying my hand at making a global ai, well now im trying to make it make energy making units if it needs them, well that part works but it tries to make a ton of them while the others are not done, to try to fix that i made a function to see if any unit on its team makes energy and is under construction, but for some reason the "energyMake" value in unitdef is returning 0 even on units that make energy, any ideas?
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Post by Tobi »

Code: Select all

	float windGenerator;
	float tidalGenerator;
Maybe it are wind generators or tidals? Which possibly use these UnitDef members instead of energyMake.
User avatar
Bobcatben
Posts: 120
Joined: 10 Mar 2006, 17:01

Post by Bobcatben »

well, it marks the commander as 0 and a solar panel as well, both make energy
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

if(ud==0) return;

always check return valus on GetUnitDef() for null pointers.
User avatar
Bobcatben
Posts: 120
Joined: 10 Mar 2006, 17:01

Post by Bobcatben »

it gets the name fine, it just returns 0 on the makeenergy
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

What compiler? VS 2003? 6? 2005? 2005 express?
User avatar
Bobcatben
Posts: 120
Joined: 10 Mar 2006, 17:01

Post by Bobcatben »

vs2003 the code im fiddleing with right now is...

Code: Select all

void TestGlobalAI::UnitCreated(int unit)
{
	myUnits[unit] = new UnitInfo;
	myUnits[unit]->ut = ai->UnitTable->table[aicb->GetUnitDef(unit)->id];
	myUnits[unit]->ud = aicb->GetUnitDef(unit);
	myUnits[unit]->Status = idle;
	Say("iam %s, i make %d energy",myUnits[unit]->ud->humanName.c_str(),myUnits[unit]->ud->energyMake);
}
it spits out the name fine, but says it produces 0 energy.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

That doesnt require 2 unitdef calls either....

And there's no checking on null return values whcih means there's a crashbug.

also try also printing

energyUpkeep*-1

solar collectors for some reason cost -20 to run which is the same as producing 20, it's an artefact of something in the original cavedog files.
User avatar
Bobcatben
Posts: 120
Joined: 10 Mar 2006, 17:01

Post by Bobcatben »

hmm ill try that *-1 thing, but it does 0 for the commander too which produces some, i realize i dont need 2 calls, i was just throwing together the code to get something to happen before i clean it up.

*edit* well, that didnt work :/ i dont know what todo, the whole point of trying to read the energy production was to try to detect if anything that makes energy was under construction so it wouldn't try to build a infinite amount of solars while the first one was being built.
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

solar collectors for some reason cost -20 to run which is the same as producing 20, it's an artefact of something in the original cavedog files.
It allows to disable energy production on attacks. EnergyMake is not affected by the unit being enabled/disabled.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

Aha, didnt now that.

And I'm fast coming to the opinion that it might be your setup that might be at fault.

Try:

Code: Select all

void TestGlobalAI::UnitCreated(int unit){
   const UnitDef* ud = aicb->GetUnitDef(unit);
   if(ud){
      Say("I'm %s, and I make %f energy", ud->humanName.c_str(),
              ud->energyMake);
   }else{
      Say("bad UnitDef == null");
   }
}
it is %f for floats and %d for doubles isnt it? ud->energymake is of type float..........
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Post by Tobi »

User avatar
Bobcatben
Posts: 120
Joined: 10 Mar 2006, 17:01

Post by Bobcatben »

hmmm, well that was the problem... kind of, it shows the proper energymake for the commander but solars are still 0, and i would have known it was a float if something in the taspring includes didnt mess up the intellisense database in vc2003 every few minutes :P i have to keep exiting and deleting the database for class member completion to consistently work.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

bobcat, dont use ud->energymake for solars, instead check ud->energycost for a negative value.
User avatar
Bobcatben
Posts: 120
Joined: 10 Mar 2006, 17:01

Post by Bobcatben »

well, i was hoping i could have 1 way to check if a unit produced energy, so i could have a function to see if anything that made energy was being built so it knew not to build more yet.... so what your saying is i have to treat solars differently? instead of being a universal method?
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Post by Tobi »

Basically there are 4 ways a unit can produce energy (I think):

Code: Select all

energyUpkeep < 0
energyMake > 0
windGenerator > 0
tidalGenerator > 0
(not sure about the last two)

These conditions are easily combined in an if statement, or you could even sum the energy production & cost of a unit to make sure your code can handle units that both use energy, and produce it.
User avatar
Bobcatben
Posts: 120
Joined: 10 Mar 2006, 17:01

Post by Bobcatben »

hmm, ok, ill try whipping up a if for that then.
while we are at it. is there a easy way to see if a spot on the map is underwater?
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

negative heightmap y values are udnerwater.

so 5,5,5 is above water but 5,-5,5 is 5 pixels below sea level.

Also, if you have a situation where you have a wind generator or a tidal, you have to call the interface for the energy values and not the unitdef. With wind you'll have to handle a max wind and min wind values, for which it might be best to just average them out, while specifying a minimum wind value.

taken from ubuild.cpp GetPOWER():

Code: Select all

float temp_energy = 0;
if((*pd)->energyUpkeep <0) temp_energy += -(*pd)->energyUpkeep;
if((*pd)->windGenerator>1) temp_energy += (G->cb->GetMaxWind()+G->cb->GetMinWind())/2;
if((*pd)->energyMake > 1) temp_energy += (*pd)->energyMake;
if((*pd)->tidalGenerator >0) temp_energy += G->cb->GetTidalStrength();
User avatar
PauloMorfeo
Posts: 2004
Joined: 15 Dec 2004, 20:53

Post by PauloMorfeo »

Tobi wrote:Basically there are 4 ways a unit can produce energy (I think):

Code: Select all

energyUpkeep < 0
energyMake > 0
windGenerator > 0
tidalGenerator > 0
(not sure about the last two)
...
EnergyMake are units like the commander or a nuclear fusion, which always give x Energy.

EnergyUse is used for units that need to be shutdown (like solar panels (-20) that shutdown and enter ARMOURED state whenever they are taking damage or metal makers (60)). As it seems, EnergyUse is stoped as soon as the units go "off" and that is why that system is used. (figured that out yesterday)
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Post by hughperkins »

Pseudo-ontopic, what is the calculation to determine how long it will take for a specific unitdef to construct a specific unitdef, given unlimited resources?
Post Reply

Return to “AI”