Example #1
0
// All changes need to be in SV_SendEffect(), SV_ParseEffect(),
// SV_SaveEffects(), SV_LoadEffects(), CL_ParseEffect()
void SV_LoadEffects (FILE *FH)
{
	int		idx, Total, count;
	int		c;
	unsigned int	u;

	Total = idx = -1;
	/* Since the map is freshly loaded, clear out any effects as a result of
	   the loading */
	SV_ClearEffects();

	fscanf(FH, "Effects: %d\n", &Total);
	if (Total < 0 || Total > MAX_EFFECTS)
		Host_Error ("%s: bad numeffects", __thisfunc__);

	for (count = 0 ; count < Total ; idx = -1, count++)
	{
		fscanf(FH, "Effect: %d ", &idx);
		if (idx < 0 || idx >= MAX_EFFECTS)
			Host_Error ("%s: bad index", __thisfunc__);
		fscanf(FH, "%d %f: ", &sv.Effects[idx].type, &sv.Effects[idx].expire_time);

		switch (sv.Effects[idx].type)
		{
		case CE_RAIN:
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.min_org[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.min_org[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.min_org[2]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.max_org[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.max_org[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.max_org[2]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.e_size[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.e_size[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.e_size[2]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.dir[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.dir[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.dir[2]);
			fscanf(FH, "%d ", &sv.Effects[idx].ef.Rain.color);
			fscanf(FH, "%d ", &sv.Effects[idx].ef.Rain.count);
			fscanf(FH, "%f\n", &sv.Effects[idx].ef.Rain.wait);
			break;

		case CE_SNOW:
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.min_org[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.min_org[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.min_org[2]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.max_org[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.max_org[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.max_org[2]);
			fscanf(FH, "%d ", &sv.Effects[idx].ef.Rain.flags);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.dir[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.dir[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Rain.dir[2]);
			fscanf(FH, "%d ", &sv.Effects[idx].ef.Rain.count);
			//fscanf(FH, "%d ", &sv.Effects[idx].ef.Rain.veer);
			/*
			O.S:	a linefeed is missing here. not adding
				it so as not to break existing saves.
				also see in: SV_SaveEffects().
			*/
			break;

		case CE_FOUNTAIN:
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Fountain.pos[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Fountain.pos[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Fountain.pos[2]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Fountain.angle[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Fountain.angle[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Fountain.angle[2]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Fountain.movedir[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Fountain.movedir[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Fountain.movedir[2]);
			fscanf(FH, "%d ", &sv.Effects[idx].ef.Fountain.color);
			fscanf(FH, "%d\n", &sv.Effects[idx].ef.Fountain.cnt);
			break;

		case CE_QUAKE:
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Quake.origin[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Quake.origin[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Quake.origin[2]);
			fscanf(FH, "%f\n", &sv.Effects[idx].ef.Quake.radius);
			break;

		case CE_WHITE_SMOKE:
		case CE_GREEN_SMOKE:
		case CE_GREY_SMOKE:
		case CE_RED_SMOKE:
		case CE_SLOW_WHITE_SMOKE:
		case CE_TELESMK1:
		case CE_TELESMK2:
		case CE_GHOST:
		case CE_REDCLOUD:
		case CE_ACID_MUZZFL:
		case CE_FLAMESTREAM:
		case CE_FLAMEWALL:
		case CE_FLAMEWALL2:
		case CE_ONFIRE:
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Smoke.origin[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Smoke.origin[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Smoke.origin[2]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Smoke.velocity[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Smoke.velocity[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Smoke.velocity[2]);
		/* smoke frame is a mission pack thing only: read carefully... */
		//	fscanf(FH, "%f ", &sv.Effects[idx].ef.Smoke.framelength);
		//	fscanf(FH, "%f\n", &sv.Effects[idx].ef.Smoke.frame);
			fscanf(FH, "%f", &sv.Effects[idx].ef.Smoke.framelength);
			c = fgetc (FH);	/* read one char, see what it is: */
			if (c == '\n' || c == '\r')
			{	/* 1.11 style */
				sv.Effects[idx].ef.Smoke.frame = 0;
				/* read one char until it's not an EOL char, then
				   go one char back to the correct position.    */
				while (!feof(FH) && (c == '\n' || c == '\r'))
					c = fgetc (FH);
				if (!feof(FH))
					ungetc (c, FH);
			}
			else
			{	/* 1.12 mission pack style */
				//if (c != ' ')
				//	Sys_DPrintf ("broken save ??\n");
				fscanf(FH, " %f\n", &sv.Effects[idx].ef.Smoke.frame);
			}
			break;

		case CE_SM_WHITE_FLASH:
		case CE_YELLOWRED_FLASH:
		case CE_BLUESPARK:
		case CE_YELLOWSPARK:
		case CE_SM_CIRCLE_EXP:
		case CE_BG_CIRCLE_EXP:
		case CE_SM_EXPLOSION:
		case CE_LG_EXPLOSION:
		case CE_FLOOR_EXPLOSION:
		case CE_FLOOR_EXPLOSION3:
		case CE_BLUE_EXPLOSION:
		case CE_REDSPARK:
		case CE_GREENSPARK:
		case CE_ICEHIT:
		case CE_MEDUSA_HIT:
		case CE_MEZZO_REFLECT:
		case CE_FLOOR_EXPLOSION2:
		case CE_XBOW_EXPLOSION:
		case CE_NEW_EXPLOSION:
		case CE_MAGIC_MISSILE_EXPLOSION:
		case CE_BONE_EXPLOSION:
		case CE_BLDRN_EXPL:
		case CE_BRN_BOUNCE:
		case CE_LSHOCK:
		case CE_ACID_HIT:
		case CE_ACID_SPLAT:
		case CE_ACID_EXPL:
		case CE_LBALL_EXPL:
		case CE_FBOOM:
		case CE_FIREWALL_SMALL:
		case CE_FIREWALL_MEDIUM:
		case CE_FIREWALL_LARGE:
		case CE_BOMB:
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Smoke.origin[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Smoke.origin[1]);
			fscanf(FH, "%f\n", &sv.Effects[idx].ef.Smoke.origin[2]);
			break;

		case CE_WHITE_FLASH:
		case CE_BLUE_FLASH:
		case CE_SM_BLUE_FLASH:
		case CE_RED_FLASH:
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Flash.origin[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Flash.origin[1]);
			fscanf(FH, "%f\n", &sv.Effects[idx].ef.Flash.origin[2]);
			break;

		case CE_RIDER_DEATH:
			fscanf(FH, "%f ", &sv.Effects[idx].ef.RD.origin[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.RD.origin[1]);
			fscanf(FH, "%f\n", &sv.Effects[idx].ef.RD.origin[2]);
			break;

		case CE_GRAVITYWELL:
			fscanf(FH, "%f ", &sv.Effects[idx].ef.RD.origin[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.RD.origin[1]);
			fscanf(FH, "%f", &sv.Effects[idx].ef.RD.origin[2]);
			fscanf(FH, "%d", &sv.Effects[idx].ef.RD.color);
			fscanf(FH, "%f\n", &sv.Effects[idx].ef.RD.lifetime);
			break;

		case CE_TELEPORTERPUFFS:
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Teleporter.origin[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Teleporter.origin[1]);
			fscanf(FH, "%f\n", &sv.Effects[idx].ef.Teleporter.origin[2]);
			break;

		case CE_TELEPORTERBODY:
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Teleporter.origin[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Teleporter.origin[1]);
			fscanf(FH, "%f\n", &sv.Effects[idx].ef.Teleporter.origin[2]);
			break;

		case CE_BONESHARD:
		case CE_BONESHRAPNEL:
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Missile.origin[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Missile.origin[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Missile.origin[2]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Missile.velocity[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Missile.velocity[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Missile.velocity[2]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Missile.angle[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Missile.angle[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Missile.angle[2]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Missile.avelocity[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Missile.avelocity[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Missile.avelocity[2]);
			/*
			O.S:	a linefeed is missing here. not adding
				it so as not to break existing saves.
				also see in: SV_SaveEffects().
			*/
			break;

		case CE_CHUNK:
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Chunk.origin[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Chunk.origin[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Chunk.origin[2]);
			fscanf(FH, "%u ", &u);
			sv.Effects[idx].ef.Chunk.type = u & 0xff;
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Chunk.srcVel[0]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Chunk.srcVel[1]);
			fscanf(FH, "%f ", &sv.Effects[idx].ef.Chunk.srcVel[2]);
			fscanf(FH, "%u ", &u);
			sv.Effects[idx].ef.Chunk.numChunks = u & 0xff;
			/*
			O.S:	a linefeed is missing here. not adding
				it so as not to break existing saves.
				also see in: SV_SaveEffects().
			*/
			break;

		default:
			Host_Error ("%s: bad type", __thisfunc__);
			break;
		}
	}
}
Example #2
0
// All changes need to be in SV_SendEffect(), SV_ParseEffect(),
// SV_SaveEffects(), SV_LoadEffects(), CL_ParseEffect()
void SV_LoadEffects(FILE *FH)
{
	int index,Total,count;

	// Since the map is freshly loaded, clear out any effects as a result of
	// the loading
	SV_ClearEffects();

	fscanf(FH,"Effects: %d\n",&Total);

	for(count=0;count<Total;count++)
	{
		fscanf(FH,"Effect: %d ",&index);
		fscanf(FH,"%d %f: ",&sv.Effects[index].type,&sv.Effects[index].expire_time);

		switch(sv.Effects[index].type)
		{
			case CE_RAIN:
				fscanf(FH, "%f ", &sv.Effects[index].Rain.min_org[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Rain.min_org[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Rain.min_org[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Rain.max_org[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Rain.max_org[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Rain.max_org[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Rain.e_size[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Rain.e_size[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Rain.e_size[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Rain.dir[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Rain.dir[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Rain.dir[2]);
				fscanf(FH, "%d ", &sv.Effects[index].Rain.color);
				fscanf(FH, "%d ", &sv.Effects[index].Rain.count);
				fscanf(FH, "%f\n", &sv.Effects[index].Rain.wait);
				break;

			case CE_FOUNTAIN:
				fscanf(FH, "%f ", &sv.Effects[index].Fountain.pos[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Fountain.pos[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Fountain.pos[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Fountain.angle[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Fountain.angle[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Fountain.angle[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Fountain.movedir[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Fountain.movedir[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Fountain.movedir[2]);
				fscanf(FH, "%d ", &sv.Effects[index].Fountain.color);
				fscanf(FH, "%d\n", &sv.Effects[index].Fountain.cnt);
				break;

			case CE_QUAKE:
				fscanf(FH, "%f ", &sv.Effects[index].Quake.origin[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Quake.origin[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Quake.origin[2]);
				fscanf(FH, "%f\n", &sv.Effects[index].Quake.radius);
				break;

			case CE_WHITE_SMOKE:
			case CE_GREEN_SMOKE:
			case CE_GREY_SMOKE:
			case CE_RED_SMOKE:
			case CE_SLOW_WHITE_SMOKE:
			case CE_TELESMK1:
			case CE_TELESMK2:
			case CE_GHOST:
			case CE_REDCLOUD:
			case CE_ACID_MUZZFL:
			case CE_FLAMESTREAM:
			case CE_FLAMEWALL:
			case CE_FLAMEWALL2:
			case CE_ONFIRE:
			case CE_RIPPLE:
				fscanf(FH, "%f ", &sv.Effects[index].Smoke.origin[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Smoke.origin[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Smoke.origin[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Smoke.velocity[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Smoke.velocity[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Smoke.velocity[2]);
				fscanf(FH, "%f\n", &sv.Effects[index].Smoke.framelength);
				break;

			case CE_SM_WHITE_FLASH:
			case CE_YELLOWRED_FLASH:
			case CE_BLUESPARK:
			case CE_YELLOWSPARK:
			case CE_SM_CIRCLE_EXP:
			case CE_BG_CIRCLE_EXP:
			case CE_SM_EXPLOSION:
			case CE_SM_EXPLOSION2:
			case CE_BG_EXPLOSION:
			case CE_FLOOR_EXPLOSION:
			case CE_BLUE_EXPLOSION:
			case CE_REDSPARK:
			case CE_GREENSPARK:
			case CE_ICEHIT:
			case CE_MEDUSA_HIT:
			case CE_MEZZO_REFLECT:
			case CE_FLOOR_EXPLOSION2:
			case CE_XBOW_EXPLOSION:
			case CE_NEW_EXPLOSION:
			case CE_MAGIC_MISSILE_EXPLOSION:
			case CE_BONE_EXPLOSION:
			case CE_BLDRN_EXPL:
			case CE_BRN_BOUNCE:
			case CE_LSHOCK:
			case CE_ACID_HIT:
			case CE_ACID_SPLAT:
			case CE_ACID_EXPL:
			case CE_LBALL_EXPL:
			case CE_FBOOM:
			case CE_FIREWALL_SMALL:
			case CE_FIREWALL_MEDIUM:
			case CE_FIREWALL_LARGE:
			case CE_BOMB:

				fscanf(FH, "%f ", &sv.Effects[index].Smoke.origin[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Smoke.origin[1]);
				fscanf(FH, "%f\n", &sv.Effects[index].Smoke.origin[2]);
				break;

			case CE_WHITE_FLASH:
			case CE_BLUE_FLASH:
			case CE_SM_BLUE_FLASH:
			case CE_HWSPLITFLASH:
			case CE_RED_FLASH:
				fscanf(FH, "%f ", &sv.Effects[index].Flash.origin[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Flash.origin[1]);
				fscanf(FH, "%f\n", &sv.Effects[index].Flash.origin[2]);
				break;

			case CE_RIDER_DEATH:
				fscanf(FH, "%f ", &sv.Effects[index].RD.origin[0]);
				fscanf(FH, "%f ", &sv.Effects[index].RD.origin[1]);
				fscanf(FH, "%f\n", &sv.Effects[index].RD.origin[2]);
				break;

			case CE_TELEPORTERPUFFS:
				fscanf(FH, "%f ", &sv.Effects[index].Teleporter.origin[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Teleporter.origin[1]);
				fscanf(FH, "%f\n", &sv.Effects[index].Teleporter.origin[2]);
				break;

			case CE_TELEPORTERBODY:
				fscanf(FH, "%f ", &sv.Effects[index].Teleporter.origin[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Teleporter.origin[1]);
				fscanf(FH, "%f\n", &sv.Effects[index].Teleporter.origin[2]);
				break;

			case CE_BONESHRAPNEL:
			case CE_HWBONEBALL:
				fscanf(FH, "%f ", &sv.Effects[index].Missile.origin[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.origin[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.origin[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.velocity[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.velocity[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.velocity[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.angle[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.angle[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.angle[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.avelocity[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.avelocity[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.avelocity[2]);
				break;
			case CE_BONESHARD:
			case CE_HWRAVENSTAFF:
			case CE_HWRAVENPOWER:
			case CE_HWMISSILESTAR:
			case CE_HWEIDOLONSTAR:
				fscanf(FH, "%f ", &sv.Effects[index].Missile.origin[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.origin[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.origin[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.velocity[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.velocity[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.velocity[2]);
				break;
			case CE_DEATHBUBBLES:
				fscanf(FH, "%f ", &sv.Effects[index].Bubble.offset[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Bubble.offset[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Bubble.offset[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Bubble.owner);
				fscanf(FH, "%f ", &sv.Effects[index].Bubble.count);
				break;
			case CE_HWDRILLA:
				fscanf(FH, "%f ", &sv.Effects[index].Missile.origin[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.origin[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.origin[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.angle[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.angle[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.angle[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Missile.speed);
				break;
			case CE_SCARABCHAIN:
				fscanf(FH, "%f ", &sv.Effects[index].Chain.origin[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Chain.origin[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Chain.origin[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Chain.owner);
				fscanf(FH, "%f ", &sv.Effects[index].Chain.material);
				fscanf(FH, "%f ", &sv.Effects[index].Chain.tag);
				break;
			case CE_HWSHEEPINATOR:
			case CE_HWXBOWSHOOT:
				fscanf(FH, "%f ", &sv.Effects[index].Xbow.origin[5][0]);
				fscanf(FH, "%f ", &sv.Effects[index].Xbow.origin[5][1]);
				fscanf(FH, "%f ", &sv.Effects[index].Xbow.origin[5][2]);
				fscanf(FH, "%f ", &sv.Effects[index].Xbow.angle[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Xbow.angle[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Xbow.angle[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Xbow.bolts);
				fscanf(FH, "%f ", &sv.Effects[index].Xbow.activebolts);
				fscanf(FH, "%f ", &sv.Effects[index].Xbow.turnedbolts);
				break;
			case CE_TRIPMINESTILL:
			case CE_TRIPMINE:
				fscanf(FH, "%f ", &sv.Effects[index].Chain.origin[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Chain.origin[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Chain.origin[2]);
				fscanf(FH, "%f ", &sv.Effects[index].Chain.velocity[0]);
				fscanf(FH, "%f ", &sv.Effects[index].Chain.velocity[1]);
				fscanf(FH, "%f ", &sv.Effects[index].Chain.velocity[2]);
				break;
			default:
				PR_RunError ("SV_SaveEffect: bad type");
				break;
		}
	}
}