int Sonic_CheckRight(Object* self, int* outAngle, int* otherDist)
{
	int dist1, dist2;
	FindWall(self, self->y - self->width, self->x + self->height, 0xE, 0, 16, &dist1, &v_anglebuffer)
	FindWall(self, self->y + self->width, self->x + self->height, 0xE, 0, 16, &dist2, &v_b_F76A)
	return Sonic_CheckCommon(dist1, dist2, 0xC0, outAngle, otherDist);
}
// aka "Sonic_DontRunOnWalls" which is the dumbest name
int Sonic_CheckUp(Object* self, int* outAngle, int* otherDist)
{
	int dist1, dist2;
	FindFloor(self, (self->y - self->height) ^ 0xF, self->x + self->width, 0xE, 0x1000, -16, &dist1, &v_anglebuffer)
	FindWall(self, (self->y - self->height) ^ 0xF, self->x - self->width, 0xE, 0x1000, -16, &dist2, &v_b_F76A)
	return Sonic_CheckCommon(dist1, dist2, 0x80, outAngle, otherDist);
}
int Sonic_GetRightWallDistAngle(Object* self, int x, int y, int* outAngle)
{
	int dist;
	FindWall(self, y, x + 10, 0xE, 0, 16, &dist, &v_anglebuffer);

	if(outAngle)
		*outAngle = (v_anglebuffer & 1) ? -0x40 : v_anglebuffer;

	return dist;
}
int Sonic_GetLeftWallDistAngle(Object* self, int x, int y, int* outAngle)
{
	int dist;
	FindWall(self, y, (x - 10) ^ 0xF, 0xE, 0x800, -16, &dist, &v_anglebuffer);

	if(outAngle)
		*outAngle = (v_anglebuffer & 1) ? 0x40 : v_anglebuffer;

	return dist;
}
Ejemplo n.º 5
0
bool CMine::CalcDeltaLights (double fLightScale, int force, int recursion_depth) 
{
	// initialize totals
CDSegment *srcseg, *childseg;
int source_segnum, child_segnum;
double effect[4];

GameInfo ().delta_lights.count = 0;
GameInfo ().dl_indices.count = 0;
bool bWall, bD2XLights = (level_version >= 15) && (GameInfo ().fileinfo_version >= 34);

fLightScale = 1.0; ///= 100.0;
for (source_segnum = 0, srcseg = Segments (); 
	  source_segnum < SegCount (); 
	  source_segnum++, srcseg++) {
	// skip if not marked unless we are automatically saving
	if  (!(srcseg->wall_bitmask & MARKED_MASK) && !force) 
		continue;
	// loop on all sides
	int source_sidenum;
	for (source_sidenum = 0; source_sidenum < 6; source_sidenum++) {
		INT16 tmapnum = srcseg->sides [source_sidenum].nBaseTex & 0x3fff;
		INT16 tmapnum2 = srcseg->sides [source_sidenum].nOvlTex & 0x3fff;
		INT16 trignum;
		bool bl1 = (bool) (IsLight (tmapnum) != -1);
		bool bl2 = (bool) (IsLight (tmapnum2) != -1);
		if (!(bl1 || bl2))
			continue;	// no lights on this side
		bool bCalcDeltas = false;
		// if the current side is a wall and has a light and is the target of a trigger
		// than can make the wall appear/disappear, calculate delta lights for it
		if ((bWall = (FindWall (source_segnum, source_sidenum) != NULL)) &&
			 ((trignum = FindTriggerTarget (0, source_segnum, source_sidenum)) >= 0)) {
			INT8 trigtype = Triggers (trignum)->type;
			bCalcDeltas =
				(trigtype == TT_ILLUSION_OFF) ||
				(trigtype == TT_ILLUSION_ON) ||
				(trigtype == TT_CLOSE_WALL) ||
				(trigtype == TT_OPEN_WALL) ||
				(trigtype == TT_LIGHT_OFF) ||
				(trigtype == TT_LIGHT_ON);
				 
			}
		if (!bCalcDeltas)
			bCalcDeltas = IsFlickeringLight (source_segnum, source_sidenum);
		if (!bCalcDeltas) {
			bool bb1 = IsBlastableLight (tmapnum);
			bool bb2 = IsBlastableLight (tmapnum2);
			if (bb1 == bb2)
				bCalcDeltas = bb1;	// both lights blastable or not
			else if (!(bb1 ? bl2 : bl1))	// i.e. one light blastable and the other texture not a non-blastable light 
				bCalcDeltas = true;
			}
		if (!bCalcDeltas) {	//check if light is target of a "light on/off" trigger
			int trignum = FindTriggerTarget (0, source_segnum, source_sidenum);
			if ((trignum >= 0) && (Triggers (trignum)->type >= TT_LIGHT_OFF))
				bCalcDeltas = true;
			}
		if (!bCalcDeltas)
			continue;
		// only set lights for textures which have a nOvlTex
		//if (tmapnum2 == 0)
		//	continue;

		INT16 srcwall = srcseg->sides [source_sidenum].nWall;
		if ((srcseg->children [source_sidenum] != -1) &&
			 ((srcwall >= GameInfo ().walls.count) || (Walls (srcwall)->type == WALL_OPEN)))
			continue;

//		if ((IsLight (tmapnum) == -1) && (IsLight (tmapnum2) == -1))
//			continue;
		if (GameInfo ().dl_indices.count >= MAX_DL_INDICES) {
			char szMsg [256];
			sprintf (szMsg, " Light tool: Too many dynamic lights at render depth %d", recursion_depth);
			DEBUGMSG (szMsg);
			return false;
			}

		vms_vector A,source_center;

		// get index number and increment total number of dl_indices
		int dl_index_num = (int)GameInfo ().dl_indices.count++;
		dl_index *pdli = DLIndex (dl_index_num);
		if (bD2XLights) {
			pdli->d2x.segnum = source_segnum;
			pdli->d2x.sidenum = source_sidenum;
			pdli->d2x.count = 0; // will be incremented below
			}
		else {
			pdli->d2.segnum = source_segnum;
			pdli->d2.sidenum = source_sidenum;
			pdli->d2.count = 0; // will be incremented below
			}
		pdli->d2.index = (INT16)GameInfo ().delta_lights.count;

		// find orthogonal angle of source segment
		CalcOrthoVector(A,source_segnum,source_sidenum);
		// remember to flip the sign since we want it to point inward
		A.x = -A.x;
		A.y = -A.y;
		A.z = -A.z;

		// calculate the center of the source segment
		CalcCenter(source_center,source_segnum,source_sidenum);

		// mark those Segments () within N children of current cube
		//(note: this is done once per light instead of once per segment
		//       even though some Segments () have multiple lights.
		//       This actually reduces the number of calls since most
		//       Segments () do not have lights)

		int h;
		for (h = 0; h < SegCount (); h++)
			Segments (h)->seg_number = -1;
		SetSegmentChildNum (srcseg, source_segnum, recursion_depth);
		srcseg->seg_number = recursion_depth;

		// setup source corner vertex for length calculation later
		vms_vector source_corner[4];
		int j;
		for (j = 0; j < 4; j++) {
			UINT8 vertnum = side_vert[source_sidenum][j];
			int h = srcseg->verts[vertnum];
			source_corner[j].x = Vertices (h)->x;
			source_corner[j].y = Vertices (h)->y;
			source_corner[j].z = Vertices (h)->z;
			}

		// loop on child Segments ()
		for (child_segnum = 0, childseg = Segments ();
			  child_segnum < SegCount ();
			  child_segnum++, childseg++) {
			if (childseg->seg_number < 0)
				continue;
			// loop on child sides
			int child_sidenum;
			for (child_sidenum = 0; child_sidenum < 6; child_sidenum++) {
				// if texture has a child..
#ifdef _DEBUG
			CBRK (source_segnum == 6 && source_sidenum == 2 &&
				child_segnum == 10 && child_sidenum == 1);
#endif
				if (childseg->children[child_sidenum] >= 0) {
					UINT16 nWall = childseg->sides[child_sidenum].nWall;
					// .. if there is no wall ..
					if (nWall >= GameInfo ().walls.count)
						continue;
					// .. or its not a door ..
					if (Walls (nWall)->type == WALL_OPEN) 
						continue; // don't put light because there is no texture here
					}
				// don't affect non-flickering light emitting textures (e.g. lava)
				tmapnum = childseg->sides [child_sidenum].nBaseTex;
				tmapnum2 = childseg->sides [child_sidenum].nOvlTex & 0x3fff;
				if (m_nNoLightDeltas == 1) {
					if (((IsLight (tmapnum) >= 0) || (IsLight (tmapnum2) >= 0))
						 && !IsFlickeringLight (child_segnum, child_sidenum))
						continue;
					}
				else if ((m_nNoLightDeltas == 2) && (IsLava (tmapnum) || IsLava (tmapnum2)))
					continue;
				// if the child side is the same as the source side, then set light and continue
				if (child_sidenum == source_sidenum && child_segnum == source_segnum) {
					if ((GameInfo ().delta_lights.count >= MAX_DELTA_LIGHTS) || 
						 (bD2XLights ? pdli->d2x.count == 8191 : pdli->d2.count == 255)) {
						char szMsg [256];
						sprintf (szMsg, " Light tool: Too many dynamic lights at render depth %d", recursion_depth);
						DEBUGMSG (szMsg);
						return false;
						}
					delta_light *dl = DeltaLights (GameInfo ().delta_lights.count++);
					dl->segnum = child_segnum;
					dl->sidenum = child_sidenum;
					dl->dummy = 0;
					dl->vert_light [0] =
					dl->vert_light [1] =
					dl->vert_light [2] =
					dl->vert_light [3] = (UINT8) min (32, 32 * fLightScale);
					if (bD2XLights)
						pdli->d2x.count++;
					else
						pdli->d2.count++;
					continue;
					}

				// calculate vector between center of source segment and center of child
#ifdef _DEBUG
					CBRK (child_segnum == qqq1 && child_sidenum == qqq2);
#endif
					if (CalcSideLights (child_segnum, child_sidenum, source_center, source_corner, A, effect, fLightScale, bWall)) {
						theApp.SetModified (TRUE);
						if ((GameInfo ().delta_lights.count >= MAX_DELTA_LIGHTS) || 
							 (bD2XLights ? pdli->d2x.count == 8191 : pdli->d2.count == 255)) {
							char szMsg [256];
							sprintf (szMsg, " Light tool: Too many dynamic lights at render depth %d", recursion_depth);
							DEBUGMSG (szMsg);
							return false;
							}
						delta_light *dl = DeltaLights (GameInfo ().delta_lights.count++);
						dl->segnum = child_segnum;
						dl->sidenum = child_sidenum;
						dl->dummy = 0;
						int iCorner;
						for (iCorner = 0; iCorner < 4; iCorner++)
							dl->vert_light [iCorner] = (UINT8) min(32, effect [iCorner]);
						if (bD2XLights)
							pdli->d2x.count++;
						else
							pdli->d2.count++;
						}
					}
				}
//			}
		}
	}
return true;
}