⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sv_save.c

📁 使用Doom引擎开发的著名游戏《毁灭巫师》的源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
		}	}	randomclass = rClass;	// Redirect anything targeting a player mobj	if(TargetPlayerAddrs)	{		for(i = 0; i < TargetPlayerCount; i++)		{			*TargetPlayerAddrs[i] = (int)targetPlayerMobj;		}		Z_Free(TargetPlayerAddrs);	}	// Destroy all things touching players	for(i = 0; i < MAXPLAYERS; i++)	{		if(playeringame[i])		{			P_TeleportMove(players[i].mo, players[i].mo->x,				players[i].mo->y);		}	}	// Restore trashed globals	inv_ptr = inventoryPtr;	curpos = currentInvPos;	// Launch waiting scripts	if(!deathmatch)	{		P_CheckACSStore();	}	// For single play, save immediately into the reborn slot	if(!netgame)	{		SV_SaveGame(REBORN_SLOT, REBORN_DESCRIPTION);	}}//==========================================================================//// SV_GetRebornSlot////==========================================================================int SV_GetRebornSlot(void){	return(REBORN_SLOT);}//==========================================================================//// SV_RebornSlotAvailable//// Returns true if the reborn slot is available.////==========================================================================boolean SV_RebornSlotAvailable(void){	char fileName[100];	sprintf(fileName, "%shex%d.hxs", SavePath, REBORN_SLOT);	return ExistingFile(fileName);}//==========================================================================//// SV_LoadMap////==========================================================================void SV_LoadMap(void){	char fileName[100];	// Load a base level	G_InitNew(gameskill, gameepisode, gamemap);	// Remove all thinkers	RemoveAllThinkers();	// Create the name	sprintf(fileName, "%shex6%02d.hxs", SavePath, gamemap);	// Load the file	M_ReadFile(fileName, &SaveBuffer);	SavePtr.b = SaveBuffer;	AssertSegment(ASEG_MAP_HEADER);	// Read the level timer	leveltime = GET_LONG;	UnarchiveWorld();	UnarchivePolyobjs();	UnarchiveMobjs();	UnarchiveThinkers();	UnarchiveScripts();	UnarchiveSounds();	UnarchiveMisc();	AssertSegment(ASEG_END);	// Free mobj list and save buffer	Z_Free(MobjList);	Z_Free(SaveBuffer);}//==========================================================================//// SV_InitBaseSlot////==========================================================================void SV_InitBaseSlot(void){	ClearSaveSlot(BASE_SLOT);}//==========================================================================//// ArchivePlayers////==========================================================================static void ArchivePlayers(void){	int i;	int j;	player_t tempPlayer;	StreamOutLong(ASEG_PLAYERS);	for(i = 0; i < MAXPLAYERS; i++)	{		StreamOutByte(playeringame[i]);	}	for(i = 0; i < MAXPLAYERS; i++)	{		if(!playeringame[i])		{			continue;		}		StreamOutByte(PlayerClass[i]);		tempPlayer = players[i];		for(j = 0; j < NUMPSPRITES; j++)		{			if(tempPlayer.psprites[j].state)			{				tempPlayer.psprites[j].state =					(state_t *)(tempPlayer.psprites[j].state-states);			}		}		StreamOutBuffer(&tempPlayer, sizeof(player_t));	}}//==========================================================================//// UnarchivePlayers////==========================================================================static void UnarchivePlayers(void){	int i, j;	AssertSegment(ASEG_PLAYERS);	for(i = 0; i < MAXPLAYERS; i++)	{		playeringame[i] = GET_BYTE;	}	for(i = 0; i < MAXPLAYERS; i++)	{		if(!playeringame[i])		{			continue;		}		PlayerClass[i] = GET_BYTE;		memcpy(&players[i], SavePtr.b, sizeof(player_t));		SavePtr.b += sizeof(player_t);		players[i].mo = NULL; // Will be set when unarc thinker		P_ClearMessage(&players[i]);		players[i].attacker = NULL;		players[i].poisoner = NULL;		for(j = 0; j < NUMPSPRITES; j++)		{			if(players[i].psprites[j].state)			{				players[i].psprites[j].state =					&states[(int)players[i].psprites[j].state];			}		}	}}//==========================================================================//// ArchiveWorld////==========================================================================static void ArchiveWorld(void){	int i;	int j;	sector_t *sec;	line_t *li;	side_t *si;	StreamOutLong(ASEG_WORLD);	for(i = 0, sec = sectors; i < numsectors; i++, sec++)	{		StreamOutWord(sec->floorheight>>FRACBITS);		StreamOutWord(sec->ceilingheight>>FRACBITS);		StreamOutWord(sec->floorpic);		StreamOutWord(sec->ceilingpic);		StreamOutWord(sec->lightlevel);		StreamOutWord(sec->special);		StreamOutWord(sec->tag);		StreamOutWord(sec->seqType);	}	for(i = 0, li = lines; i < numlines; i++, li++)	{		StreamOutWord(li->flags);		StreamOutByte(li->special);		StreamOutByte(li->arg1);		StreamOutByte(li->arg2);		StreamOutByte(li->arg3);		StreamOutByte(li->arg4);		StreamOutByte(li->arg5);		for(j = 0; j < 2; j++)		{			if(li->sidenum[j] == -1)			{				continue;			}			si = &sides[li->sidenum[j]];			StreamOutWord(si->textureoffset>>FRACBITS);			StreamOutWord(si->rowoffset>>FRACBITS);			StreamOutWord(si->toptexture);			StreamOutWord(si->bottomtexture);			StreamOutWord(si->midtexture);		}	}}//==========================================================================//// UnarchiveWorld////==========================================================================static void UnarchiveWorld(void){	int i;	int j;	sector_t *sec;	line_t *li;	side_t *si;	AssertSegment(ASEG_WORLD);	for(i = 0, sec = sectors; i < numsectors; i++, sec++)	{		sec->floorheight = GET_WORD<<FRACBITS;		sec->ceilingheight = GET_WORD<<FRACBITS;		sec->floorpic = GET_WORD;		sec->ceilingpic = GET_WORD;		sec->lightlevel = GET_WORD;		sec->special = GET_WORD;		sec->tag = GET_WORD;		sec->seqType = GET_WORD;		sec->specialdata = 0;		sec->soundtarget = 0;	}	for(i = 0, li = lines; i < numlines; i++, li++)	{		li->flags = GET_WORD;		li->special = GET_BYTE;		li->arg1 = GET_BYTE;		li->arg2 = GET_BYTE;		li->arg3 = GET_BYTE;		li->arg4 = GET_BYTE;		li->arg5 = GET_BYTE;		for(j = 0; j < 2; j++)		{			if(li->sidenum[j] == -1)			{				continue;			}			si = &sides[li->sidenum[j]];			si->textureoffset = GET_WORD<<FRACBITS;			si->rowoffset = GET_WORD<<FRACBITS;			si->toptexture = GET_WORD;			si->bottomtexture = GET_WORD;			si->midtexture = GET_WORD;		}	}}//==========================================================================//// SetMobjArchiveNums//// Sets the archive numbers in all mobj structs.  Also sets the MobjCount// global.  Ignores player mobjs if SavingPlayers is false.////==========================================================================static void SetMobjArchiveNums(void){	mobj_t *mobj;	thinker_t *thinker;	MobjCount = 0;	for(thinker = thinkercap.next; thinker != &thinkercap;		thinker = thinker->next)	{		if(thinker->function == P_MobjThinker)		{			mobj = (mobj_t *)thinker;			if(mobj->player && !SavingPlayers)			{ // Skipping player mobjs				continue;			}			mobj->archiveNum = MobjCount++;		}	}}//==========================================================================//// ArchiveMobjs////==========================================================================static void ArchiveMobjs(void){	int count;	thinker_t *thinker;	mobj_t tempMobj;	StreamOutLong(ASEG_MOBJS);	StreamOutLong(MobjCount);	count = 0;	for(thinker = thinkercap.next; thinker != &thinkercap;		thinker = thinker->next)	{		if(thinker->function != P_MobjThinker)		{ // Not a mobj thinker			continue;		}		if(((mobj_t *)thinker)->player && !SavingPlayers)		{ // Skipping player mobjs			continue;		}		count++;		memcpy(&tempMobj, thinker, sizeof(mobj_t));		MangleMobj(&tempMobj);		StreamOutBuffer(&tempMobj, sizeof(mobj_t));	}	if(count != MobjCount)	{		I_Error("ArchiveMobjs: bad mobj count");	}}//==========================================================================//// UnarchiveMobjs////==========================================================================static void UnarchiveMobjs(void){	int i;	mobj_t *mobj;	AssertSegment(ASEG_MOBJS);	TargetPlayerAddrs = Z_Malloc(MAX_TARGET_PLAYERS*sizeof(int *),		PU_STATIC, NULL);	TargetPlayerCount = 0;	MobjCount = GET_LONG;	MobjList = Z_Malloc(MobjCount*sizeof(mobj_t *), PU_STATIC, NULL);	for(i = 0; i < MobjCount; i++)	{		MobjList[i] = Z_Malloc(sizeof(mobj_t), PU_LEVEL, NULL);	}	for(i = 0; i < MobjCount; i++)	{		mobj = MobjList[i];		memcpy(mobj, SavePtr.b, sizeof(mobj_t));		SavePtr.b += sizeof(mobj_t);		mobj->thinker.function = P_MobjThinker;		RestoreMobj(mobj);		P_AddThinker(&mobj->thinker);	}	P_CreateTIDList();	P_InitCreatureCorpseQueue(true); // true = scan for corpses}//==========================================================================//// MangleMobj////==========================================================================static void MangleMobj(mobj_t *mobj){	boolean corpse;	corpse = mobj->flags&MF_CORPSE;	mobj->state = (state_t *)(mobj->state-states);	if(mobj->player)	{		mobj->player = (player_t *)((mobj->player-players)+1);	}	if(corpse)	{		mobj->target = (mobj_t *)MOBJ_NULL;	}	else	{		mobj->target = (mobj_t *)GetMobjNum(mobj->target);	}	switch(mobj->type)	{		// Just special1		case MT_BISH_FX:		case MT_HOLY_FX:		case MT_DRAGON:		case MT_THRUSTFLOOR_UP:		case MT_THRUSTFLOOR_DOWN:		case MT_MINOTAUR:		case MT_SORCFX1:		case MT_MSTAFF_FX2:			if(corpse)			{				mobj->special1 = MOBJ_NULL;			}			else			{				mobj->special1 = GetMobjNum((mobj_t *)mobj->special1);			}			break;		// Just special2		case MT_LIGHTNING_FLOOR:		case MT_LIGHTNING_ZAP:			if(corpse)			{				mobj->special2 = MOBJ_NULL;			}			else			{				mobj->special2 = GetMobjNum((mobj_t *)mobj->special2);			}			break;		// Both special1 and special2		case MT_HOLY_TAIL:		case MT_LIGHTNING_CEILING:			if(corpse)			{				mobj->special1 = MOBJ_NULL;				mobj->special2 = MOBJ_NULL;			}			else			{				mobj->special1 = GetMobjNum((mobj_t *)mobj->special1);				mobj->special2 = GetMobjNum((mobj_t *)mobj->special2);			}			break;		// Miscellaneous		case MT_KORAX:			mobj->special1 = 0; // Searching index			break;		default:			break;	}}//==========================================================================//// GetMobjNum////==========================================================================static int GetMobjNum(mobj_t *mobj){	if(mobj == NULL)	{		return MOBJ_NULL;	}	if(mobj->player && !SavingPlayers)	{		return MOBJ_XX_PLAYER;	}	return mobj->archiveNum;}//==========================================================================//// RestoreMobj////==========================================================================static void RestoreMobj(mobj_t *mobj){	mobj->state = &states[(int)mobj->state];	if(mobj->player)	{		mobj->player = &players[(int)mobj->player-1];		mobj->player->mo = mobj;	}	P_SetThingPosition(mobj);	mobj->info = &mobjinfo[mobj->type];	mobj->floorz = mobj->subsector->sector->floorheight;	mobj->ceilingz = mobj->subsector->sector->ceilingheight;	SetMobjPtr((int *)&mobj->target);	switch(mobj->type)	{		// Just special1		case MT_BISH_FX:		case MT_HOLY_FX:		case MT_DRAGON:		case MT_THRUSTFLOOR_UP:		case MT_THRUSTFLOOR_DOWN:		case MT_MINOTAUR:		case MT_SORCFX1:			SetMobjPtr(&mobj->special1);			break;		// Just special2		case MT_LIGHTNING_FLOOR:		case MT_LIGHTNING_ZAP:			SetMobjPtr(&mobj->special2);			break;		// Both special1 and special2		case MT_HOLY_TAIL:		case MT_LIGHTNING_CEILING:			SetMobjPtr(&mobj->special1);			SetMobjPtr(&mobj->special2);			break;		default:			break;	}}//==========================================================================//// SetMobjPtr////==========================================================================static void SetMobjPtr(int *archiveNum){	if(*archiveNum == MOBJ_NULL)	{		*archiveNum = 0;		return;	}	if(*archiveNum == MOBJ_XX_PLAYER)	{		if(TargetPlayerCount == MAX_TARGET_PLAYERS)		{			I_Error("RestoreMobj: exceeded MAX_TARGET_PLAYERS");		}		TargetPlayerAddrs[TargetPlayerCount++] = archiveNum;		*archiveNum = 0;		return;	}	*archiveNum = (int)MobjList[*archiveNum];}//==========================================================================//// ArchiveThinkers////==========================================================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -