示例#1
0
文件: trigger.cpp 项目: paud/d2x-xl
INT16 CMine::FindTriggerWall (INT16 trignum)
{
CDWall *wall = Walls ();
int wallnum;
for (wallnum = GameInfo ().walls.count; wallnum; wallnum--, wall++)
	if (wall->trigger == trignum)
		return wall - Walls ();
return GameInfo ().walls.count;
}
示例#2
0
文件: light.cpp 项目: paud/d2x-xl
void CMine::CalcAverageCornerLight (bool bAll)
{
  int segnum,pt,i,vertnum,count,sidenum,uvnum;
  UINT16 max_brightness;

// smooth corner light by averaging all corners which share a vertex
theApp.SetModified (TRUE);
for (vertnum = 0; vertnum < VertCount (); vertnum++) {
	if (bAll || (*VertStatus (vertnum) & MARKED_MASK)) {
		max_brightness = 0;
		count = 0;
		// find all Segments () which share this point
		CDSegment *seg = Segments ();
		for (segnum = 0; segnum < SegCount (); segnum++, seg++) {
			for (pt = 0; pt < 8; pt++) {
				if (seg->verts[pt] == vertnum) {
					// add all the uvls for this point
					for (i = 0; i < 3; i++) {
						sidenum = point_sides[pt][i];
						uvnum = point_corners[pt][i];
						if ((seg->children[sidenum] < 0) || 
							 (seg->sides[sidenum].nWall < GameInfo ().walls.count)) {
							max_brightness = max(max_brightness,(UINT16)seg->sides[sidenum].uvls[uvnum].l);
							count++;
							}
						}
					}
				}
			}
		// now go back and set these light values
		if (count > 0) {
			theApp.SetModified (TRUE);
			//	max_brightness = min(max_brightness,0x8000L);
			CDSegment *seg = Segments ();
			for (segnum=0;segnum<SegCount ();segnum++, seg++) {
				for (pt=0;pt<8;pt++) {
					if (seg->verts[pt] == vertnum) {
						for (i=0;i<3;i++) {
							sidenum = point_sides[pt][i];
							uvnum = point_corners[pt][i];
							if ((seg->children[sidenum] < 0) || 
								 (seg->sides[sidenum].nWall < GameInfo ().walls.count)) {
								seg->sides[sidenum].uvls[uvnum].l = max_brightness;
								}
							}
						}
					}
				}
			}
		}
	}
}
示例#3
0
文件: trigger.cpp 项目: paud/d2x-xl
INT16 CMine::FindTriggerWall (INT16 *trignum, INT16 segnum, INT16 sidenum)
{
GetCurrent (segnum, sidenum);
CDWall *wall = Walls ();
int wallnum;
for (wallnum = GameInfo ().walls.count; wallnum; wallnum--, wall++) {
	if ((wall->segnum == segnum) && (wall->sidenum == sidenum)) {
		*trignum = wall->trigger;
		return wall - Walls ();
		}
	}
*trignum = NO_TRIGGER;
return GameInfo ().walls.count;
}
示例#4
0
文件: light.cpp 项目: paud/d2x-xl
void CMine::SetSegmentChildNum (CDSegment *pRoot, INT16 segnum,INT16 recursion_level) 
{
	INT16			sidenum, child, nImprove = 0;
	UINT16		nWall;
	CDSegment	*seg = Segments () + segnum;
	CDSegment	*prevSeg = NULL;
	bool			bMarkChildren = false;

// mark each child if child number is lower
for (sidenum = 0; sidenum < MAX_SIDES_PER_SEGMENT; sidenum++) {
	// Skip if this is a door
	nWall = seg->sides [sidenum].nWall;
	// .. if there is a wall and its a door
	if ((nWall < GameInfo ().walls.count) && (Walls (nWall)->type == WALL_DOOR))
		continue;
	// mark segment if it has a child
	child = seg->children [sidenum];
	if ((child > -1) && (child < SegCount ()) && (recursion_level > seg->seg_number)) {
		if (seg->seg_number >= 0)
			++nImprove;
/*
		if (pRoot) {
			UnlinkSeg (seg, pRoot);
			LinkSeg (seg, pRoot);
			}
*/
		seg->seg_number = recursion_level;
		bMarkChildren = true;
		break;
		}
	}
//return if segment has no children or max recursion depth is reached
if (!bMarkChildren || (recursion_level == 1))
	return;

// check each side of this segment for more children
for (sidenum = 0; sidenum < MAX_SIDES_PER_SEGMENT; sidenum++) {
	// skip if there is a wall and its a door
	nWall = seg->sides [sidenum].nWall;
	if ((nWall < GameInfo ().walls.count) && (Walls (nWall)->type == WALL_DOOR))
		continue;
	// check child
	child = seg->children [sidenum];
	if ((child > -1) && (child < SegCount ()))
		SetSegmentChildNum (pRoot, child, recursion_level - 1);
	}
}
示例#5
0
文件: light.cpp 项目: paud/d2x-xl
int CMine::FindDeltaLight (INT16 segnum, INT16 sidenum, INT16 *pi)
{
	int	i = pi ? *pi : 0;
	int	j	= (int)GameInfo ().dl_indices.count++;
	dl_index	*pdli = DLIndex ();

if ((level_version >= 15) && (GameInfo ().fileinfo_version >= 34)) {
	for (; i < j; i++, pdli++)
		if ((pdli->d2x.segnum == segnum) && (pdli->d2x.sidenum = (UINT8) sidenum))
			return i;
	}
else {
	for (; i < j; i++, pdli++)
		if ((pdli->d2.segnum == segnum) && (pdli->d2.sidenum = (UINT8) sidenum))
			return i;
	}
return -1;
}
示例#6
0
文件: trigger.cpp 项目: paud/d2x-xl
INT16 CMine::FindTriggerTarget (INT16 trignum, INT16 segnum, INT16 sidenum)
{
CDTrigger *trigger = Triggers ();
int i, j;

for (i = trignum; i < GameInfo ().triggers.count; i++, trigger++)
	for (j = 0; j < trigger->num_links; j++)
		if ((trigger->seg [j] == segnum) && (trigger->side [j] == sidenum))
			return i;
return -1;
}
示例#7
0
文件: trigger.cpp 项目: paud/d2x-xl
void CMine::DeleteTrigger (INT16 nTrigger) 
{
	INT16	i, nSegment, nSide, nWall;

if (nTrigger < 0) {
	nWall = CurrSeg ()->sides [Current ()->side].nWall;
	if (nWall >= GameInfo ().walls.count)
		return;
	nTrigger = Walls (nWall)->trigger;
	}
if (nTrigger >= GameInfo ().triggers.count)
	return;
// update all Walls () who point to Triggers () higher than this one
// and unlink all Walls () who point to deleted trigger (should be only one wall)
theApp.SetModified (TRUE);
theApp.LockUndo ();
CDWall *wallP = Walls ();
for (i = GameInfo ().walls.count; i; i--, wallP++)
	if ((wallP->trigger != NO_TRIGGER) && (wallP->trigger > nTrigger))
		wallP->trigger--;
	else if (wallP->trigger == nTrigger) {
		wallP->trigger = NO_TRIGGER;
		nSegment = wallP->segnum;
		nSide = wallP->sidenum;
		}
// remove trigger from array
//for (i=nTrigger;i<GameInfo ().triggers.count-1;i++)
// update number of Triggers ()
CDTrigger *trigP = Triggers ();
for (i = NumTriggers (); i; i--, trigP++)
	if (trigP->type >= TT_MASTER)
		DeleteTriggerTarget (trigP, nSegment, nSide, false);
if (nTrigger < --GameInfo ().triggers.count)
	memcpy(Triggers (nTrigger), Triggers (nTrigger + 1), (GameInfo ().triggers.count - nTrigger) * sizeof(CDTrigger));
theApp.UnlockUndo ();
theApp.MineView ()->Refresh ();
AutoLinkExitToReactor();
}
示例#8
0
文件: trigger.cpp 项目: paud/d2x-xl
void CMine::DeleteTriggerTargets (INT16 segnum, INT16 sidenum) 
{
int i;

for (i = 0; i < GameInfo ().triggers.count; i++)
	if (DeleteTriggerTarget (Triggers (i), segnum, sidenum))
		i--;

for (i = 0; i < NumObjTriggers (); i++)
	if (DeleteTriggerTarget (ObjTriggers (i), segnum, sidenum, false)) {
		DeleteObjTrigger (i);
		i--;
		}
}
示例#9
0
文件: control.cpp 项目: paud/d2x-xl
//
// Action - Updates control center Triggers () so that exit door opens
//          when the reactor blows up.  Removes any invalid cube/sides
//          from control_center_triggers if they exist.
//------------------------------------------------------------------------
void auto_link_exit_to_reactor() 
{
  INT16 	linknum,control,num_links,segnum,sidenum;
  UINT16	wallnum;
  UINT8 	trignum;
  bool 	found;

  control = 0; // only 0 used by the game Descent

  // remove items from list that do not point to a wall
  for (linknum=0;linknum<control_center_triggers[control].num_links;linknum++) {
    num_links =  control_center_triggers[control].num_links;
    segnum = control_center_triggers[control].seg[linknum];
    sidenum = control_center_triggers[control].side[linknum];
    // search for Walls () that have a exit of type trigger
    found = FALSE;
    for (wallnum=0;wallnum<GameInfo ().walls_howmany;wallnum++) {
      if (Walls (wallnum)->segnum == segnum && Walls ()[wallnum].sidenum == sidenum) {
        found = TRUE;
        break;
      }
    }
//        trignum = Walls (wallnum)->trigger;
//      if (trignum >= 0 && trignum <GameInfo ().triggers_howmany) {
//        if (Triggers ()[trignum].flags & (TRIGGER_EXIT | TRIGGER_SECRET_EXIT)) {
//	    found = TRUE;
//	    break;
//        }
//      }
//    }
//  }
    if (!found) {
      if (num_links > 0) { // just in case
        // move last link into this deleted link's spot
        control_center_triggers[control].seg [linknum] =
          control_center_triggers[control].seg[num_links-1];
        control_center_triggers[control].side[linknum] =
          control_center_triggers[control].side[num_links-1];
        control_center_triggers[control].seg [num_links-1] = 0;
        control_center_triggers[control].side[num_links-1] = 0;
        control_center_triggers[control].num_links--;
      }
    }
  }

  // add exit to list if not already in list
  // search for walls that have a exit of type trigger
  num_links =  control_center_triggers[control].num_links;
  for (wallnum=0;wallnum<GameInfo ().walls_howmany;wallnum++) {
    trignum = Walls (wallnum)->trigger;
    if (trignum >= 0 && trignum <GameInfo ().triggers_howmany) {
      if (   file_type == RDL_FILE &&
	     Triggers ()[trignum].flags & (TRIGGER_EXIT | TRIGGER_SECRET_EXIT)
	  ||
	     file_type != RDL_FILE &&
	     (Triggers ()[trignum].type == TT_EXIT || Triggers ()[trignum].type == TT_SECRET_EXIT)
	 ) {
	// see if cube,side is already on the list
	segnum = (INT16)Walls (wallnum)->segnum;
	sidenum =(INT16)Walls (wallnum)->sidenum;
	found = FALSE;
        for (linknum=0;linknum<num_links;linknum++) {
          if (segnum == control_center_triggers[control].seg[linknum] && 
	      sidenum == control_center_triggers[control].side[linknum]) {
	    found = TRUE;
            break;
	  }
	}
        // if not already on the list, add it
	if (!found) {
	  linknum = control_center_triggers[control].num_links;
	  control_center_triggers[control].seg[linknum] = segnum;
          control_center_triggers[control].side[linknum] = sidenum;
          control_center_triggers[control].num_links++;
	}
      }
    }
  }
}
示例#10
0
void	CGameSpy_Browser::ReadServerInfo	(ServerInfo* pServerInfo, void* pServer)
{
	CStringTable st;

	if (!pServer || !pServerInfo) return;
	sprintf_s(pServerInfo->m_Address, "%s:%d", xrGS_SBServerGetPublicAddress(pServer), xrGS_SBServerGetPublicQueryPort(pServer));
	sprintf_s(pServerInfo->m_HostName, "%s", xrGS_SBServerGetPublicAddress(pServer));
	sprintf_s(pServerInfo->m_ServerName, "%s", xrGS_SBServerGetStringValue(pServer, m_pQR2->xrGS_RegisteredKey(HOSTNAME_KEY), pServerInfo->m_HostName));

	sprintf_s(pServerInfo->m_SessionName, "%s", xrGS_SBServerGetStringValue(pServer, m_pQR2->xrGS_RegisteredKey(MAPNAME_KEY), "Unknown"));	
	sprintf_s(pServerInfo->m_ServerGameType, "%s", xrGS_SBServerGetStringValue(pServer, m_pQR2->xrGS_RegisteredKey(GAMETYPE_KEY), "Unknown"));
	pServerInfo->m_bPassword	= xrGS_SBServerGetBoolValue(pServer, m_pQR2->xrGS_RegisteredKey(PASSWORD_KEY), SBFalse) == SBTrue;
	pServerInfo->m_bUserPass	= xrGS_SBServerGetBoolValue(pServer, m_pQR2->xrGS_RegisteredKey(G_USER_PASSWORD_KEY), SBFalse) == SBTrue;

#ifdef BATTLEYE
	pServerInfo->m_bBattlEye	= xrGS_SBServerGetBoolValue(pServer, m_pQR2->xrGS_RegisteredKey(G_BATTLEYE_KEY), SBFalse) == SBTrue;
#endif // BATTLEYE

	pServerInfo->m_Ping = (s16)(xrGS_SBServerGetPing(pServer) & 0xffff);
	pServerInfo->m_ServerNumPlayers = (s16)xrGS_SBServerGetIntValue(pServer, m_pQR2->xrGS_RegisteredKey(NUMPLAYERS_KEY), 0);
	pServerInfo->m_ServerMaxPlayers = (s16)xrGS_SBServerGetIntValue(pServer, m_pQR2->xrGS_RegisteredKey(MAXPLAYERS_KEY), 32);
	pServerInfo->m_ServerNumTeams = (s16)xrGS_SBServerGetIntValue(pServer, m_pQR2->xrGS_RegisteredKey(NUMTEAMS_KEY), 0);
	pServerInfo->m_Port		= (s16)xrGS_SBServerGetIntValue(pServer, m_pQR2->xrGS_RegisteredKey(HOSTPORT_KEY), 0);
	pServerInfo->m_HPort	= (s16)xrGS_SBServerGetPublicQueryPort(pServer);
	pServerInfo->m_bDedicated	= (xrGS_SBServerGetBoolValue(pServer, m_pQR2->xrGS_RegisteredKey(DEDICATED_KEY), SBFalse)) == SBTrue;
	pServerInfo->m_GameType = (u8)xrGS_SBServerGetIntValue(pServer, m_pQR2->xrGS_RegisteredKey(GAMETYPE_NAME_KEY), 0);
	if (pServerInfo->m_GameType == 0)
	{
		if (!xr_strcmp(pServerInfo->m_ServerGameType, "deathmatch"))
			pServerInfo->m_GameType = GAME_DEATHMATCH;
		else if (!xr_strcmp(pServerInfo->m_ServerGameType, "teamdeathmatch"))
			pServerInfo->m_GameType = GAME_TEAMDEATHMATCH;
		else if (!xr_strcmp(pServerInfo->m_ServerGameType, "artefacthunt"))
			pServerInfo->m_GameType = GAME_ARTEFACTHUNT;
	}
	sprintf_s(pServerInfo->m_ServerVersion, "%s", xrGS_SBServerGetStringValue(pServer, m_pQR2->xrGS_RegisteredKey(GAMEVER_KEY), "--"));

	//--------- Read Game Infos ---------------------------//
	pServerInfo->m_aInfos.clear();
	pServerInfo->m_aPlayers.clear();
	pServerInfo->m_aTeams.clear();
	//-------------------------------------------------------//
	if (xrGS_SBServerHasFullKeys(pServer) == SBFalse) return;

//	pServerInfo->m_aInfos.push_back(GameInfo("Version:", pServerInfo->m_ServerVersion));
	pServerInfo->m_aInfos.push_back(GameInfo(*st.translate("mp_si_servername"), pServerInfo->m_ServerName));
	pServerInfo->m_aInfos.push_back(GameInfo(*st.translate("mp_si_version"), pServerInfo->m_ServerVersion));
	
#ifdef BATTLEYE
	ADD_BOOL_INFO(pServerInfo, pServer, "BattlEye", G_BATTLEYE_KEY);
#endif // BATTLEYE

	ADD_INT_INFO_N (pServerInfo, pServer, 1, "Max ping", "", G_MAX_PING_KEY);	
	ADD_BOOL_INFO(pServerInfo, pServer, *st.translate("mp_si_maprotation"), G_MAP_ROTATION_KEY);
	
	pServerInfo->m_aInfos.push_back(
		GameInfo(*st.translate("mp_si_voting"), 
		(xrGS_SBServerGetBoolValue(pServer, m_pQR2->xrGS_RegisteredKey(G_VOTING_ENABLED_KEY), SBFalse) == SBTrue) ?
			*st.translate("mp_si_enabled") : *st.translate("mp_si_disabled")));

//	ADD_BOOL_INFO(pServerInfo, pServer, *st.translate("mp_si_voting"), G_VOTING_ENABLED_KEY);
	//-----------------------------------------------------------------------
	pServerInfo->m_aInfos.push_back(GameInfo(*st.translate("mp_si_spectatormodes"), ""));
	int SpectrModes = xrGS_SBServerGetIntValue(pServer, m_pQR2->xrGS_RegisteredKey(G_SPECTATOR_MODES_KEY), 0);
	
	pServerInfo->m_aInfos.push_back(GameInfo(*st.translate("mp_si_free_fly"), ((SpectrModes & (1<<CSpectator::eacFreeFly	)) != 0) ? *st.translate("mp_si_yes") : *st.translate("mp_si_no")));
	pServerInfo->m_aInfos.push_back(GameInfo(*st.translate("mp_si_first_eye"), ((SpectrModes & (1<<CSpectator::eacFirstEye	)) != 0) ? *st.translate("mp_si_yes") : *st.translate("mp_si_no")));
	pServerInfo->m_aInfos.push_back(GameInfo(*st.translate("mp_si_look_at"), ((SpectrModes & (1<<CSpectator::eacLookAt	)) != 0) ? *st.translate("mp_si_yes") : *st.translate("mp_si_no")));
	pServerInfo->m_aInfos.push_back(GameInfo(*st.translate("mp_si_free_look"), ((SpectrModes & (1<<CSpectator::eacFreeLook	)) != 0) ? *st.translate("mp_si_yes") : *st.translate("mp_si_no")));
	if (pServerInfo->m_GameType != GAME_DEATHMATCH)
		pServerInfo->m_aInfos.push_back(GameInfo(*st.translate("mp_si_team_only"), ((SpectrModes & (1<<CSpectator::eacMaxCam	)) != 0) ? *st.translate("mp_si_yes") : *st.translate("mp_si_no")));
	//-----------------------------------------------------------------------
	
	if (pServerInfo->m_GameType == GAME_DEATHMATCH || pServerInfo->m_GameType == GAME_TEAMDEATHMATCH) 
	{
		ADD_INT_INFO_N (pServerInfo, pServer, 1, *st.translate("mp_si_fraglimit"), "", G_FRAG_LIMIT_KEY);	
	}

	ADD_TIME_INFO(pServerInfo, pServer, 1.0f, *st.translate("mp_si_time_limit"), "%.0f %s",*st.translate("mp_si_min"), G_TIME_LIMIT_KEY);

	if (xrGS_SBServerGetIntValue(pServer, m_pQR2->xrGS_RegisteredKey(G_DAMAGE_BLOCK_TIME_KEY), 0) != 0)
	{
		pServerInfo->m_aInfos.push_back(GameInfo(*st.translate("mp_si_invinsibility"), ""));
		ADD_BOOL_INFO(pServerInfo, pServer, *st.translate("mp_si_invinsibility_indicators"), G_DAMAGE_BLOCK_INDICATOR_KEY);
		ADD_TIME_INFO(pServerInfo, pServer, 1.0f, *st.translate("mp_si_invinsibility_time"), "%.f %s",*st.translate("mp_si_sec"), G_DAMAGE_BLOCK_TIME_KEY);
	}	

	ADD_BOOL_INFO(pServerInfo, pServer, *st.translate("mp_si_anomalies"), G_ANOMALIES_ENABLED_KEY);
	if ((xrGS_SBServerGetBoolValue(pServer, m_pQR2->xrGS_RegisteredKey(G_ANOMALIES_ENABLED_KEY), SBFalse)) == SBTrue)
	{
		if (xrGS_SBServerGetIntValue(pServer, m_pQR2->xrGS_RegisteredKey(G_ANOMALIES_TIME_KEY),0) != 0)
		{
			ADD_TIME_INFO(pServerInfo, pServer, 1.0f, *st.translate("mp_si_anomalies_period"), "%.1f %s",*st.translate("mp_si_min"), G_ANOMALIES_TIME_KEY);
		}
		else
			pServerInfo->m_aInfos.push_back(GameInfo(*st.translate("mp_si_anomalies_period"), *st.translate("mp_si_infinite")));
	}

	ADD_TIME_INFO(pServerInfo, pServer, 1.0f, *st.translate("mp_si_forcerespawn"), "%.f %s",*st.translate("mp_si_sec"), G_FORCE_RESPAWN_KEY);
	ADD_TIME_INFO(pServerInfo, pServer, 1.0f, *st.translate("mp_si_warmuptime"), "%.0f %s",*st.translate("mp_si_sec"), G_WARM_UP_TIME_KEY);

	if (pServerInfo->m_GameType == GAME_TEAMDEATHMATCH || pServerInfo->m_GameType == GAME_ARTEFACTHUNT)
	{
		ADD_BOOL_INFO(pServerInfo, pServer, *st.translate("mp_si_autoteam_balance"), G_AUTO_TEAM_BALANCE_KEY);
		ADD_BOOL_INFO(pServerInfo, pServer, *st.translate("mp_si_autoteam_swap"), G_AUTO_TEAM_SWAP_KEY);
		ADD_BOOL_INFO(pServerInfo, pServer, *st.translate("mp_si_friendly_indicators"), G_FRIENDLY_INDICATORS_KEY);
		ADD_BOOL_INFO(pServerInfo, pServer, *st.translate("mp_si_friendly_names"), G_FRIENDLY_NAMES_KEY);

		ADD_INT_INFO_N (pServerInfo, pServer, 1/100.0f, *st.translate("mp_si_friendly_fire"), " %%", G_FRIENDLY_FIRE_KEY);
	};

	if (pServerInfo->m_GameType == GAME_ARTEFACTHUNT)
	{
		pServerInfo->m_aInfos.push_back(GameInfo(*st.translate("mp_si_artefacts"), ""));
		ADD_INT_INFO(pServerInfo, pServer, *st.translate("mp_si_afcount"),					G_ARTEFACTS_COUNT_KEY	);

		ADD_TIME_INFO(pServerInfo, pServer, 1.0f, *st.translate("mp_si_afstaytime"), "%.2f %s",*st.translate("mp_si_min"), G_ARTEFACT_STAY_TIME_KEY);
		ADD_TIME_INFO(pServerInfo, pServer, 1.0f, *st.translate("mp_si_afrespawntime"), "%.0f %s",*st.translate("mp_si_sec"), G_ARTEFACT_RESPAWN_TIME_KEY);

		int Reinforcement = atoi(xrGS_SBServerGetStringValue(pServer, m_pQR2->xrGS_RegisteredKey(G_REINFORCEMENT_KEY), "0"));		
		switch (Reinforcement)
		{
		case -1:
			pServerInfo->m_aInfos.push_back(GameInfo(*st.translate("mp_si_players_respawn"), *st.translate("mp_si_artefact_captured")));
			break;
		case 0:
			pServerInfo->m_aInfos.push_back(GameInfo(*st.translate("mp_si_players_respawn"), *st.translate("mp_si_any_time")));
			break;
		default:
			ADD_TIME_INFO(pServerInfo, pServer, 1.0f, *st.translate("mp_si_players_respawn"), "%.0f %s",*st.translate("mp_si_sec"), G_REINFORCEMENT_KEY);
			break;
		}

		ADD_BOOL_INFO(pServerInfo, pServer, *st.translate("mp_si_shielded_bases"),					G_SHIELDED_BASES_KEY	);
		ADD_BOOL_INFO(pServerInfo, pServer, *st.translate("mp_si_return_players"),					G_RETURN_PLAYERS_KEY	);
		ADD_BOOL_INFO(pServerInfo, pServer, *st.translate("mp_si_afbearer_cant_sprint"),			G_BEARER_CANT_SPRINT_KEY);
	}
	
	//--------- Read Players Info -------------------------//	
	for (int i=0; i<pServerInfo->m_ServerNumPlayers; i++)
	{
		PlayerInfo PInfo;
		sprintf_s(PInfo.Name, "%s", xrGS_SBServerGetPlayerStringValue(pServer, i,	"player", "Unknown"));
		PInfo.Frags =		s16(xrGS_SBServerGetPlayerIntValue(pServer, i,			"score", 0));
		PInfo.Deaths =		u16(xrGS_SBServerGetPlayerIntValue(pServer, i,			"deaths", 0));
		PInfo.Rank =		u8(xrGS_SBServerGetPlayerIntValue(pServer, i,			"skill", 0));
		PInfo.Team =		u8(xrGS_SBServerGetPlayerIntValue(pServer, i,			"team", 0));
		PInfo.Spectator =	(xrGS_SBServerGetPlayerIntValue(pServer, i,				"spectator", 1)) != 0;
		PInfo.Artefacts =	u8(xrGS_SBServerGetPlayerIntValue(pServer, i,			"artefacts", 0));

		pServerInfo->m_aPlayers.push_back(PInfo);
	};
	//----------- Read Team Info ---------------------------//
	if (pServerInfo->m_GameType == GAME_TEAMDEATHMATCH || pServerInfo->m_GameType == GAME_ARTEFACTHUNT)
	{
		for (int i=0; i<pServerInfo->m_ServerNumTeams; i++)
		{
			TeamInfo TI;
			TI.Score = u8(xrGS_SBServerGetTeamIntValue(pServer, i, "t_score", 0));
			pServerInfo->m_aTeams.push_back(TI);
		}		
	}
};
示例#11
0
文件: light.cpp 项目: paud/d2x-xl
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;
}
示例#12
0
文件: light.cpp 项目: paud/d2x-xl
void CMine::Illuminate (
	INT16 source_segnum, 
	INT16 source_sidenum, 
	UINT32 brightness, 
	double fLightScale, 
	bool bAll, bool 
	bCopyTexLights) 
{
CDSegment	*seg = Segments ();
CDSegment	*child_seg;
double		effect[4];
// find orthogonal angle of source segment
vms_vector A;

//fLightScale /= 100.0;
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
vms_vector source_center;
CalcCenter (source_center,source_segnum,source_sidenum);
if ((source_segnum == 911) && (source_sidenum == 3))
	A = A;
// mark those Segments () within N children of current cube

// set child numbers
//Segments ()[source_segnum].seg_number = m_lightRenderDepth;
int i;
for (i = SegCount (); i; i--, seg++)
	seg->seg_number = -1;
SetSegmentChildNum (NULL, source_segnum, m_lightRenderDepth);
CDColor *plc = LightColor (source_segnum, source_sidenum);
if (!plc->index) {
	plc->index = 255;
	plc->color.r =
	plc->color.g =
	plc->color.b = 1.0;
	}
if (UseTexColors () && bCopyTexLights) {
	CDColor	*psc = LightColor (source_segnum, source_sidenum, false);
	*psc = *plc;
	}
seg = Segments (source_segnum);
seg->seg_number = m_lightRenderDepth;
bool bWall = false; //FindWall (source_segnum, source_sidenum) != NULL;
// loop on child Segments ()
int child_segnum;
for (child_segnum=0, child_seg = Segments ();child_segnum<SegCount ();child_segnum++, child_seg++) {
	// skip if this is not viewable
	if (child_seg->seg_number < 0) 
		continue;
	// skip if not marked
//	if (!(bAll || (child_seg->wall_bitmask & MARKED_MASK)))
//		continue;
	// setup source corner vertex for length calculation later
	vms_vector source_corner[4];
	int j;
	for (j = 0; j < 4; j++) {
		int vertnum = side_vert [source_sidenum][j];
		int h = seg->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 sides
	int child_sidenum;
	for (child_sidenum = 0; child_sidenum < 6; child_sidenum++) {
		// if side has a child..
		if (!(bAll || SideIsMarked (child_segnum, child_sidenum)))
			continue;
		if (child_seg->children[child_sidenum] >= 0) {
			UINT16 nWall = child_seg->sides[child_sidenum].nWall;
			// .. but there is no wall ..
			if (nWall >= GameInfo ().walls.count)
				continue;
				// .. or its not a door ..
			if (Walls (nWall)->type == WALL_OPEN)
				continue;
			}

//		CBRK (psc->index > 0);
		// if the child side is the same as the source side, then set light and continue
#ifdef _DEBUG
		CBRK (child_segnum == qqq1 && child_sidenum == qqq2);
#endif
		if (child_sidenum == source_sidenum && child_segnum == source_segnum) {
			uvl		*uvlP = child_seg->sides [child_sidenum].uvls;
			UINT32	vBr, lBr;

			theApp.SetModified (TRUE);
			int j;
			for (j = 0; j < 4; j++, uvlP++) {
				CDColor *pvc = VertexColors (child_seg->verts [side_vert [child_sidenum][j]]);
				vBr = (UINT16) uvlP->l;
				lBr = (UINT32) (brightness * fLightScale);
				BlendColors (plc, pvc, lBr, vBr);
				vBr += lBr;
				vBr = min (0x8000, vBr);
				uvlP->l = (UINT16) vBr;
				}
			continue;
			}

		// calculate vector between center of source segment and center of child
//		CBRK (child_segnum == 1 && child_sidenum == 2);
		if (CalcSideLights (child_segnum, child_sidenum, source_center, source_corner, A, effect, fLightScale, bWall)) {
				UINT32	vBr, lBr;	//vertex brightness, light brightness
				uvl		*uvlP = child_seg->sides [child_sidenum].uvls;

			theApp.SetModified (TRUE);
			int j;
			for (j = 0; j < 4; j++, uvlP++) {
				CDColor *pvc = VertexColors (child_seg->verts [side_vert [child_sidenum][j]]);
				if (child_seg->verts [side_vert [child_sidenum][j]] == 2368)
					j = j;
				vBr = (UINT16) uvlP->l;
				lBr = (UINT16) (brightness * effect [j] / 32);
				BlendColors (plc, pvc, lBr, vBr);
				vBr += lBr;
				vBr = min (0x8000, vBr);
				uvlP->l = (UINT16) vBr;
				}
			}
		}
	}
}
示例#13
0
文件: trigger.cpp 项目: paud/d2x-xl
CDTrigger *CMine::AddTrigger (UINT16 wallnum, INT16 type, BOOL bAutoAddWall) 
{
	INT16 flags;
	INT16 segnum, sidenum, trignum;
	static INT16 defWallTypes [NUM_TRIGGER_TYPES] = {
		WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_ILLUSION, 
		WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, 
		WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_OPEN, WALL_ILLUSION,
		WALL_OPEN, WALL_OPEN
		};
	static INT16 defWallTextures [NUM_TRIGGER_TYPES] = {
		0, 0, 0, 0, 426, 
		0, 0, 0, 0, 0, 
		0, 0, 0, 0, 426,
		0, 0
		};

// check if there's already a trigger on the current side
wallnum = FindTriggerWall (&trignum);
if (trignum != NO_TRIGGER) {
	ErrorMsg ("There is already a trigger on this side");
	return NULL;
	}
if (GameInfo ().triggers.count >= MAX_TRIGGERS) {
	ErrorMsg ("The maximum number of triggers has been reached.");
	return NULL;
	}
// if no wall at current side, try to add a wall of proper type
bool bUndo = theApp.SetModified (TRUE);
theApp.LockUndo ();
if (CurrSide ()->nWall >= GameInfo ().walls.count) {
	if (bAutoAddWall) {
		if (GameInfo ().walls.count >= MAX_WALLS) {
			ErrorMsg ("Cannot add a wall to this side,\nsince the maximum number of walls is already reached.");
			return NULL;
			}
		segnum = sidenum = -1;
		GetCurrent (segnum, sidenum);
		if (!AddWall (-1, -1, (Segments (segnum)->children [sidenum] < 0) ? WALL_OVERLAY : defWallTypes [type], 0, 0, -1, defWallTextures [type])) {
			ErrorMsg ("Cannot add a wall for this trigger.");
			theApp.ResetModified (bUndo);
			return NULL;
			}
		}
	else {
		ErrorMsg ("You must add a wall to this side before you can add a trigger.");
		return NULL;
		}
	}
// if D1, then convert type to flag value
if (file_type == RDL_FILE) {
	switch(type) {
		case TT_OPEN_DOOR:
			flags = TRIGGER_CONTROL_DOORS;
			break;
		case TT_MATCEN:
			flags = TRIGGER_MATCEN;
			break;
		case TT_EXIT:
			flags = TRIGGER_EXIT;
			break;
		case TT_SECRET_EXIT:
			flags = TRIGGER_SECRET_EXIT;
			break;
		case TT_ILLUSION_OFF:
			flags = TRIGGER_ILLUSION_OFF;
			break;
		case TT_ILLUSION_ON:
			flags = TRIGGER_ILLUSION_ON;
			break;
		case TT_ENERGY_DRAIN:
			flags = TRIGGER_ENERGY_DRAIN;
			break;
		case TT_SHIELD_DAMAGE:
			flags = TRIGGER_SHIELD_DAMAGE;
			break;
		default:
			flags = 0;
		}
	type = 0;
	}
else
	flags = 0;

trignum = (UINT16) GameInfo ().triggers.count;
// set new trigger data
InitTrigger (Triggers (trignum), type, flags);
// link trigger to the wall
Walls (wallnum)->trigger = (UINT8) trignum;
// update number of Triggers ()
GameInfo ().triggers.count++;
AutoLinkExitToReactor();
theApp.UnlockUndo ();
theApp.MineView ()->Refresh ();
return Triggers (trignum);
}
示例#14
0
文件: trigger.cpp 项目: paud/d2x-xl
void CMine::AutoLinkExitToReactor () 
{
  INT16 	linknum,control,num_links,segnum,sidenum;
  UINT16	wallnum;
  INT8 	trignum;
  bool 	found;

  control = 0; // only 0 used by the game Descent
  control_center_trigger *ccTrigger = CCTriggers (control);

theApp.SetModified (TRUE);
theApp.LockUndo ();
// remove items from list that do not point to a wall
for (linknum = 0; linknum < ccTrigger->num_links; linknum++) {
	num_links = ccTrigger->num_links;
	segnum = ccTrigger->seg [linknum];
	sidenum = ccTrigger->side [linknum];
	// search for Walls () that have a exit of type trigger
	found = FALSE;
	for (wallnum=0;wallnum<GameInfo ().walls.count;wallnum++) {
		if (Walls (wallnum)->segnum == segnum && Walls (wallnum)->sidenum == sidenum) {
		found = TRUE;
		break;
		}
	}
	if (!found) {
		if (num_links > 0) { // just in case
			// move last link into this deleted link's spot
			ccTrigger->seg [linknum] = ccTrigger->seg [num_links-1];
			ccTrigger->side [linknum] = ccTrigger->side [num_links-1];
			ccTrigger->seg [num_links-1] = 0;
			ccTrigger->side [num_links-1] = 0;
			ccTrigger->num_links--;
			}
		}
	}

// add exit to list if not already in list
// search for Walls () that have a exit of type trigger
num_links =  ccTrigger->num_links;
for (wallnum = 0; wallnum < GameInfo ().walls.count; wallnum++) {
	trignum = Walls (wallnum)->trigger;
	if (trignum >= 0 && trignum <GameInfo ().triggers.count) {
		if ((file_type == RDL_FILE) ?
			 Triggers (trignum)->flags & (TRIGGER_EXIT | TRIGGER_SECRET_EXIT) :
			 Triggers (trignum)->type == TT_EXIT || Triggers (trignum)->type == TT_SECRET_EXIT) {
			// see if cube,side is already on the list
			segnum = (INT16)Walls (wallnum)->segnum;
			sidenum =(INT16)Walls (wallnum)->sidenum;
			found = FALSE;
			for (linknum = 0; linknum < num_links; linknum++) {
				if (segnum == ccTrigger->seg [linknum] && sidenum == ccTrigger->side [linknum]) {
					found = TRUE;
					break;
					}
				}
			// if not already on the list, add it
			if (!found) {
				linknum = ccTrigger->num_links;
				ccTrigger->seg [linknum] = segnum;
				ccTrigger->side [linknum] = sidenum;
				ccTrigger->num_links++;
				}
			}
		}
	}
theApp.UnlockUndo ();
}
示例#15
0
文件: modify.cpp 项目: paud/d2x-xl
void CMine::SpinSelection(double angle) 
{
	int nSegment = Current ()->segment;
	int nSide = Current ()->side;
	CDSegment *seg = Segments (nSegment);
	CDObject *obj;
	vms_vector center,opp_center;
	INT16 i;

#ifdef SPIN_RELATIVE
	double xspin,yspin,zspin;
	vms_vector rel [3];
#endif

/* calculate segment pointer */
switch (m_selectMode) {
	case POINT_MODE:
		ErrorMsg ("Cannot spin a point");
		break; /* can't spin a point */
	
	case LINE_MODE:
		ErrorMsg ("Cannot spin a line");
		break; /* line spinning not supported */
	
	case SIDE_MODE: // spin side around its center in the plane of the side
		// calculate center of current side
		theApp.SetModified (TRUE);
		center.x = center.y = center.z = 0;
		for (i = 0; i < 4; i++) {
			center.x += Vertices (seg->verts [side_vert [nSide][i]])->x;
			center.y += Vertices (seg->verts [side_vert [nSide][i]])->y;
			center.z += Vertices (seg->verts [side_vert [nSide][i]])->z;
			}
		center.x /= 4;
		center.y /= 4;
		center.z /= 4;
		// calculate orthogonal vector from lines which intersect point 0
		//       |x  y  z |
		// AxB = |ax ay az| = x(aybz-azby), y(azbx-axbz), z(axby-aybx)
		//       |bx by bz|
		struct vector {double x,y,z;};
		struct vector a,b,c;
		double length;
		INT16 vertnum1,vertnum2;

		vertnum1 = seg->verts [side_vert [nSide][0]];
		vertnum2 = seg->verts [side_vert [nSide][1]];
		a.x = (double)(Vertices (vertnum2)->x - Vertices (vertnum1)->x);
		a.y = (double)(Vertices (vertnum2)->y - Vertices (vertnum1)->y);
		a.z = (double)(Vertices (vertnum2)->z - Vertices (vertnum1)->z);
		vertnum1 = seg->verts [side_vert [nSide][0]];
		vertnum2 = seg->verts [side_vert [nSide][3]];
		b.x = (double)(Vertices (vertnum2)->x - Vertices (vertnum1)->x);
		b.y = (double)(Vertices (vertnum2)->y - Vertices (vertnum1)->y);
		b.z = (double)(Vertices (vertnum2)->z - Vertices (vertnum1)->z);
		c.x = a.y*b.z - a.z*b.y;
		c.y = a.z*b.x - a.x*b.z;
		c.z = a.x*b.y - a.y*b.x;
		// normalize the vector
		length = sqrt(c.x*c.x + c.y*c.y + c.z*c.z);
		c.x /= length;
		c.y /= length;
		c.z /= length;
		// set sign (since vert numbers for most sides don't follow right-handed convention)
		if (nSide!=1 && nSide!=5) {
			c.x = -c.x;
			c.y = -c.y;
			c.z = -c.z;
			}
		// set opposite center
		opp_center.x = center.x + (FIX)(0x10000L*c.x);
		opp_center.y = center.y + (FIX)(0x10000L*c.y);
		opp_center.z = center.z + (FIX)(0x10000L*c.z);
		/* rotate points around a line */
		for (i = 0; i < 4; i++) {
			RotateVertex(Vertices (seg->verts [side_vert [nSide][i]]),
			&center,&opp_center,angle);
			}
		break;


	case CUBE_MODE:	// spin cube around the center of the cube using screen's perspective
		// calculate center of current cube
		theApp.SetModified (TRUE);
		center.x = center.y = center.z = 0;
		for (i = 0; i < 8; i++) {
			center.x += Vertices (seg->verts [i])->x;
			center.y += Vertices (seg->verts [i])->y;
			center.z += Vertices (seg->verts [i])->z;
			}
		center.x /= 8;
		center.y /= 8;
		center.z /= 8;
		// calculate center of oppisite current side
		opp_center.x = opp_center.y = opp_center.z = 0;
		for (i = 0; i < 4; i++) {
			opp_center.x += Vertices (seg->verts [opp_side_vert [nSide][i]])->x;
			opp_center.y += Vertices (seg->verts [opp_side_vert [nSide][i]])->y;
			opp_center.z += Vertices (seg->verts [opp_side_vert [nSide][i]])->z;
			}
		opp_center.x /= 4;
		opp_center.y /= 4;
		opp_center.z /= 4;
		// rotate points about a point
		for (i = 0; i < 8; i++)
			RotateVertex(Vertices (seg->verts [i]),&center,&opp_center,angle);
		break;

	case OBJECT_MODE:	// spin object vector
		theApp.SetModified (TRUE);
		vms_matrix *orient;
		orient = (Current ()->object == GameInfo ().objects.count) ? &SecretOrient () : &CurrObj ()->orient;
		switch (nSide) {
			case 0:
				RotateVmsMatrix(orient,angle,'x');
				break;
			case 2:
				RotateVmsMatrix(orient,-angle,'x');
				break;
			case 1:
				RotateVmsMatrix(orient,-angle,'y');
				break;
			case 3:
				RotateVmsMatrix(orient,angle,'y');
				break;
			case 4:
				RotateVmsMatrix(orient,angle,'z');
				break;
			case 5:
				RotateVmsMatrix(orient,-angle,'z');
				break;
			}
#ifdef SPIN_RELATIVE
		// calculate angles to spin the side into the x-y plane
		// use points 0,1, and 2 of the side
		// make point0 the origin
		// and get coordinates of points 1 and 2 relative to point 0
		for (i=0;i<3;i++) {
			rel [i].x = vertices [seg->verts [side_vert [nSide][i]]].x - vertices [seg->verts [side_vert [nSide][0]]].x;
			rel [i].y = vertices [seg->verts [side_vert [nSide][i]]].y - vertices [seg->verts [side_vert [nSide][0]]].y;
			rel [i].z = vertices [seg->verts [side_vert [nSide][i]]].z - vertices [seg->verts [side_vert [nSide][0]]].z;
			}
		// calculate z-axis spin angle to rotate point1 so it lies in x-y plane
		zspin = (rel [1].x==rel [1].y) ? PI/4 : atan2(rel [1].y,rel [1].x);
		// spin all 3 points on z axis
		for (i=0;i<3;i++)
			RotateVmsVector(&rel [i],zspin,'z');
		// calculate y-axis spin angle to rotate point1 so it lies on x axis
		yspin = (rel [1].z==rel [1].x) ? PI/4 : atan2(rel [1].z,rel [1].x);
		// spin points 1 and 2 on y axis (don't need to spin point 0 since it is at 0,0,0)
		for (i=1;i<=2;i++)
			RotateVmsVector(&rel [i],yspin,'y');
		// calculate x-axis spin angle to rotate point2 so it lies in x-y plane
		xspin = (rel [2].z==rel [2].y) ? PI/4 : atan2(rel [2].z,rel [2].y);
		// spin points 2 on x axis (don't need to spin point 1 since it is on the x-axis
		RotateVmsVector(&rel [2],xspin,'x');
		RotateVmsMatrix(&obj->orient,zspin,'z');
		RotateVmsMatrix(&obj->orient,yspin,'y');
		RotateVmsMatrix(&obj->orient,xspin,'x');
		RotateVmsMatrix(&obj->orient,-xspin,'x');
		RotateVmsMatrix(&obj->orient,-yspin,'y');
		RotateVmsMatrix(&obj->orient,-zspin,'z');
#endif //SPIN_RELATIVE
		break;

	case BLOCK_MODE:
		theApp.SetModified (TRUE);
		// calculate center of current cube
		center.x = center.y = center.z = 0;
		for (i = 0; i < 8; i++) {
			center.x += Vertices (seg->verts [i])->x;
			center.y += Vertices (seg->verts [i])->y;
			center.z += Vertices (seg->verts [i])->z;
			}
		center.x /= 8;
		center.y /= 8;
		center.z /= 8;
		// calculate center of oppisite current side
		opp_center.x = opp_center.y = opp_center.z = 0;
		for (i = 0; i < 4; i++) {
			opp_center.x += Vertices (seg->verts [opp_side_vert [nSide][i]])->x;
			opp_center.y += Vertices (seg->verts [opp_side_vert [nSide][i]])->y;
			opp_center.z += Vertices (seg->verts [opp_side_vert [nSide][i]])->z;
			}
		opp_center.x /= 4;
		opp_center.y /= 4;
		opp_center.z /= 4;
		// rotate points about a point
		for (i=0;i<VertCount ();i++)
			if (*VertStatus (i) & MARKED_MASK)
				RotateVertex(Vertices (i),&center,&opp_center,angle);
		// rotate Objects () within marked cubes
		obj = Objects ();
		for (i = GameInfo ().objects.count; i; i--, obj++)
			if (Segments (obj->segnum)->wall_bitmask & MARKED_MASK)
				RotateVertex(&obj->pos, &center, &opp_center, angle);
		break;
	}
}
示例#16
0
文件: modify.cpp 项目: paud/d2x-xl
void CMine::MoveOn (char axis,INT32 inc) 
{
int nSegment = Current ()->segment;
int nSide = Current ()->side;
int nPoint = Current ()->point;
int nLine = Current ()->line;
CDSegment *seg = Segments (nSegment);
INT16 i;

theApp.SetModified (TRUE);
switch (m_selectMode) {
	case POINT_MODE:
		switch (axis) {
			case 'X':
				Vertices (seg->verts [side_vert [nSide][nPoint]])->x += inc;
				break;
			case 'Y':
				Vertices (seg->verts [side_vert [nSide][nPoint]])->y += inc;
				break;
			case 'Z':
				Vertices (seg->verts [side_vert [nSide][nPoint]])->z += inc;
				break;
			}
		break;

	case LINE_MODE:
		switch (axis) {
			case 'X':
				Vertices (seg->verts [line_vert [side_line [nSide][nLine]][0]])->x += inc;
				Vertices (seg->verts [line_vert [side_line [nSide][nLine]][1]])->x += inc;
				break;
			case 'Y':
				Vertices (seg->verts [line_vert [side_line [nSide][nLine]][0]])->y += inc;
				Vertices (seg->verts [line_vert [side_line [nSide][nLine]][1]])->y += inc;
				break;
			case 'Z':
				Vertices (seg->verts [line_vert [side_line [nSide][nLine]][0]])->z += inc;
				Vertices (seg->verts [line_vert [side_line [nSide][nLine]][1]])->z += inc;
				break;
			}
		break;

	case SIDE_MODE:
		switch (axis) {
			case 'X':
			for (i = 0; i < 4; i++)
				Vertices (seg->verts [side_vert [nSide][i]])->x += inc;
			break;
		case 'Y':
			for (i = 0; i < 4; i++)
				Vertices (seg->verts [side_vert [nSide][i]])->y += inc;
			break;
		case 'Z':
			for (i = 0; i < 4; i++)
				Vertices (seg->verts [side_vert [nSide][i]])->z += inc;
			break;
		}
		break;

	case CUBE_MODE:
		switch (axis) {
			case 'X':
				for (i = 0; i < 8; i++)
					Vertices (seg->verts [i])->x += inc;
				for (i = 0; i < GameInfo ().objects.count; i++)
					if (Objects (i)->segnum == nSegment)
						Objects (i)->pos.x += inc;
				break;
			case 'Y':
				for (i = 0; i < 8; i++)
					Vertices (seg->verts [i])->y += inc;
				for (i = 0; i < GameInfo ().objects.count; i++) 
					if (Objects (i)->segnum == nSegment)
						Objects (i)->pos.y += inc;
				break;
			case 'Z':
				for (i = 0; i < 8; i++)
					Vertices (seg->verts [i])->z += inc;
				for (i = 0; i < GameInfo ().objects.count; i++) 
					if (Objects (i)->segnum == nSegment) 
						Objects (i)->pos.z += inc;
				break;
			}
	break;

	case OBJECT_MODE:
		switch (axis) {
			case 'X':
				CurrObj ()->pos.x += inc;
				break;
			case 'Y':
				CurrObj ()->pos.y += inc;
				break;
			case 'Z':
				CurrObj ()->pos.z += inc;
				break;
		}
	break;

	case BLOCK_MODE:
		CDObject *obj = Objects ();
		switch (axis) {
			case 'X':
				for (i = 0; i < MAX_VERTICES; i++)
					if (*VertStatus (i) & MARKED_MASK)
						Vertices (i)->x += inc;
				for (i = GameInfo ().objects.count; i; i--, obj++)
					if (obj->segnum >= 0)
						if (Segments (obj->segnum)->wall_bitmask & MARKED_MASK)
							obj->pos.x += inc;
				break;
			case 'Y':
				for (i = 0; i < MAX_VERTICES; i++)
					if (*VertStatus (i) & MARKED_MASK)
						Vertices (i)->y += inc;
				for (i = GameInfo ().objects.count; i; i--, obj++)
					if (obj->segnum >= 0)
						if (Segments (obj->segnum)->wall_bitmask & MARKED_MASK)
							obj->pos.y += inc;
				break;
			case 'Z':
				for (i = 0; i < MAX_VERTICES; i++)
					if (*VertStatus (i) & MARKED_MASK)
						Vertices (i)->z += inc;
				for (i = GameInfo ().objects.count; i; i--, obj++)
					if (obj->segnum >= 0)
						if (Segments (obj->segnum)->wall_bitmask & MARKED_MASK)
							obj->pos.z += inc;
				break;
		}
	break;
	}
}