bugfixes

bugfixes

Discuss the source code and development of Spring Engine in general from a technical point of view. Patches go here too.

Moderator: Moderators

Post Reply
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

bugfixes

Post by jcnossen »

There is a bug in the CUnitHandler::GetBuildHeight(): if the given position is on the map border,
then it could be that x1 > x2 or z1 > z2. This in turn causes numBorder=0 and a division by zero.

Code: Select all

float CUnitHandler::GetBuildHeight(float3 pos, const UnitDef* unitdef)
{
	float minh=-5000;
	float maxh=5000;
	int numBorder=0;
	float borderh=0;

	float maxDif=unitdef->maxHeightDif;
	int x1 = max(0,(pos.x-(unitdef->xsize*0.5f*SQUARE_SIZE))/SQUARE_SIZE);
	int x2 = min(gs->mapx,x1+unitdef->xsize);
	int z1 = max(0,(pos.z-(unitdef->ysize*0.5f*SQUARE_SIZE))/SQUARE_SIZE);
	int z2 = min(gs->mapy,z1+unitdef->ysize);

	if (x1 > gs->mapx) x1 = gs->mapx;
	if (x2 < 0) x2 = 0;
	if (z1 > gs->mapy) z1 = gs->mapy;
	if (z2 < 0) z2 = 0;

	for(int x=x1; x<=x2; x++){
		for(int z=z1; z<=z2; z++){
			float orgh=readmap->orgheightmap[z*(gs->mapx+1)+x];
			float h=readmap->heightmap[z*(gs->mapx+1)+x];
			if(x==x1 || x==x2 || z==z1 || z==z2){
				numBorder++;
				borderh+=h;
			}
			if(minh<min(h,orgh)-maxDif)
				minh=min(h,orgh)-maxDif;
			if(maxh>max(h,orgh)+maxDif)
				maxh=max(h,orgh)+maxDif;
		}
	}
	float h=borderh/numBorder;

	if(h<minh && minh<maxh)
		h=minh+0.01;
	if(h>maxh && maxh>minh)
		h=maxh-0.01;

	return h;
}
I fixed it by inserting this into the code:

Code: Select all

	if (x1 > gs->mapx) x1 = gs->mapx;
	if (x2 < 0) x2 = 0;
	if (z1 > gs->mapy) z1 = gs->mapy;
	if (z2 < 0) z2 = 0;
-------------------------------------------------------------------------

Also this:

Code: Select all


void CGlobalAIHandler::UnitDamaged(CUnit* attacked,CUnit* attacker,float damage)
{
	if(ais[attacked->team]){
		float3 dir=helper->GetUnitErrorPos(attacker,attacked->allyteam)-attacked->pos;
		dir.Normalize();
		
		ais[attacked->team]->ai->UnitDamaged(attacked->id,attacker->id,damage,dir);
	}
}

is fixed by:

Code: Select all



void CGlobalAIHandler::UnitDamaged(CUnit* attacked,CUnit* attacker,float damage)
{
	if(ais[attacked->team]){
		float3 dir; // in case of something like fire damage, attacker is 0
		if (attacker) {
			dir=helper->GetUnitErrorPos(attacker,attacked->allyteam)-attacked->pos;
			dir.Normalize();
		}
		
		ais[attacked->team]->ai->UnitDamaged(attacked->id,attacker->id,damage,dir);
	}
}

SJ
Posts: 618
Joined: 13 Aug 2004, 17:13

Post by SJ »

Ok I included those fixes in the cvs version now, good work.
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

this one is still wrong:

Code: Select all


void CGlobalAIHandler::UnitDamaged(CUnit* attacked,CUnit* attacker,float damage)
{
	if(ais[attacked->team]){
		float3 dir;
		if(attacker){
			float3 dir=helper->GetUnitErrorPos(attacker,attacked->allyteam)-attacked->pos;
			dir.Normalize();
		}
		ais[attacked->team]->ai->UnitDamaged(attacked->id,attacker->id,damage,dir);
	}
}

currently the dir is always (0,0,0) when passed and attacker->id is illegal if attacker is 0

fix:

Code: Select all


void CGlobalAIHandler::UnitDamaged(CUnit* attacked,CUnit* attacker,float damage)
{
	if(ais[attacked->team]){
		float3 dir;
		if(attacker) {
			dir=helper->GetUnitErrorPos(attacker,attacked->allyteam)-attacked->pos;
			dir.Normalize();
		}
		ais[attacked->team]->ai->UnitDamaged(attacked->id,attacker?attacker->id:0,damage,dir);
	}
}

SJ
Posts: 618
Joined: 13 Aug 2004, 17:13

Post by SJ »

Ok fixed again :)
Post Reply

Return to “Engine”