diff --git a/src/d_netfil.c b/src/d_netfil.c
index 663bcc8643599da0bf1cbef4f0262ccc3282d682..881b7b5b20f73b5bb35b5ac0e0c73fbbf6235345 100644
--- a/src/d_netfil.c
+++ b/src/d_netfil.c
@@ -94,10 +94,20 @@ typedef struct filetran_s
 {
 	filetx_t *txlist; // Linked list of all files for the node
 	UINT32 position; // The current position in the file
-	FILE *currentfile; // The file currently being sent/received
+	boolean init; // false if we want to reset position / open a new file
 } filetran_t;
 static filetran_t transfer[MAXNETNODES];
 
+// The files currently being sent/received
+typedef struct fileused_s
+{
+	FILE *file;
+	UINT8 count;
+	UINT32 position;
+} fileused_t;
+
+static fileused_t transferFiles[UINT8_MAX + 1];
+
 // Read time of file: stat _stmtime
 // Write time of file: utime
 
@@ -760,8 +770,19 @@ static void SV_EndFileSend(INT32 node)
 		case SF_FILE: // It's a file, close it and free its filename
 			if (cv_noticedownload.value)
 				CONS_Printf("Ending file transfer (id %d) for node %d\n", p->fileid, node);
-			if (transfer[node].currentfile)
-				fclose(transfer[node].currentfile);
+			if (transferFiles[p->fileid].file)
+			{
+				if (transferFiles[p->fileid].count > 0)
+				{
+					transferFiles[p->fileid].count--;
+				}
+
+				if (transferFiles[p->fileid].count == 0)
+				{
+					fclose(transferFiles[p->fileid].file);
+					transferFiles[p->fileid].file = NULL;
+				}
+			}
 			free(p->id.filename);
 			break;
 		case SF_Z_RAM: // It's a memory block allocated with Z_Alloc or the likes, use Z_Free
@@ -778,7 +799,7 @@ static void SV_EndFileSend(INT32 node)
 	free(p);
 
 	// Indicate that the transmission is over
-	transfer[node].currentfile = NULL;
+	transfer[node].init = false;
 
 	filestosend--;
 }
@@ -842,21 +863,31 @@ void SV_FileSendTicker(void)
 		ram = f->ram;
 
 		// Open the file if it isn't open yet, or
-		if (!transfer[i].currentfile)
+		if (transfer[i].init == false)
 		{
 			if (!ram) // Sending a file
 			{
 				long filesize;
 
-				transfer[i].currentfile =
-					fopen(f->id.filename, "rb");
+				if (transferFiles[f->fileid].count == 0)
+				{
+					// It needs opened.
+					transferFiles[f->fileid].file =
+						fopen(f->id.filename, "rb");
+
+					if (!transferFiles[f->fileid].file)
+					{
+						I_Error("Can't open file %s: %s",
+							f->id.filename, strerror(errno));
+					}
+				}
 
-				if (!transfer[i].currentfile)
-					I_Error("File %s does not exist",
-						f->id.filename);
+				// Increment number of nodes using this file.
+				I_Assert(transferFiles[f->fileid].count < UINT8_MAX);
+				transferFiles[f->fileid].count++;
 
-				fseek(transfer[i].currentfile, 0, SEEK_END);
-				filesize = ftell(transfer[i].currentfile);
+				fseek(transferFiles[f->fileid].file, 0, SEEK_END);
+				filesize = ftell(transferFiles[f->fileid].file);
 
 				// Nobody wants to transfer a file bigger
 				// than 4GB!
@@ -865,23 +896,43 @@ void SV_FileSendTicker(void)
 				if (filesize == -1)
 					I_Error("Error getting filesize of %s", f->id.filename);
 
-				f->size = (UINT32)filesize;
-				fseek(transfer[i].currentfile, 0, SEEK_SET);
+				f->size = transferFiles[f->fileid].position = (UINT32)filesize;
 			}
-			else // Sending RAM
-				transfer[i].currentfile = (FILE *)1; // Set currentfile to a non-null value to indicate that it is open
+
 			transfer[i].position = 0;
+			transfer[i].init = true; // Indicate that it is open
+		}
+
+		if (!ram)
+		{
+			// Seek to the right position if we aren't already there.
+			if (transferFiles[f->fileid].position != transfer[i].position)
+			{
+				fseek(transferFiles[f->fileid].file, transfer[i].position, SEEK_SET);
+			}
 		}
 
 		// Build a packet containing a file fragment
 		p = &netbuffer->u.filetxpak;
 		size = software_MAXPACKETLENGTH - (FILETXHEADER + BASEPACKETSIZE);
-		if (f->size-transfer[i].position < size)
-			size = f->size-transfer[i].position;
+
+		if (f->size - transfer[i].position < size)
+		{
+			size = f->size - transfer[i].position;
+		}
+
 		if (ram)
+		{
 			M_Memcpy(p->data, &f->id.ram[transfer[i].position], size);
-		else if (fread(p->data, 1, size, transfer[i].currentfile) != size)
-			I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s", sizeu1(size), f->id.filename, transfer[i].position, M_FileError(transfer[i].currentfile));
+		}
+		else if (fread(p->data, 1, size, transferFiles[f->fileid].file) != size)
+		{
+			I_Error("SV_FileSendTicker: can't read %s byte on %s at %d because %s",
+				sizeu1(size), f->id.filename, transfer[i].position, M_FileError(transferFiles[f->fileid].file));
+
+			transferFiles[f->fileid].position = (UINT32)(transferFiles[f->fileid].position + size);
+		}
+
 		p->position = LONG(transfer[i].position);
 		// Put flag so receiver knows the total size
 		if (transfer[i].position + size == f->size)
@@ -891,15 +942,18 @@ void SV_FileSendTicker(void)
 
 		// Send the packet
 		if (HSendPacket(i, true, 0, FILETXHEADER + size)) // Reliable SEND
-		{ // Success
+		{
+			// Success
 			transfer[i].position = (UINT32)(transfer[i].position + size);
+
 			if (transfer[i].position == f->size) // Finish?
+			{
 				SV_EndFileSend(i);
+			}
 		}
 		else
-		{ // Not sent for some odd reason, retry at next call
-			if (!ram)
-				fseek(transfer[i].currentfile,transfer[i].position, SEEK_SET);
+		{
+			// Not sent for some odd reason, retry at next call
 			// Exit the while (can't send this one so why should i send the next?)
 			break;
 		}
diff --git a/src/m_fixed.h b/src/m_fixed.h
index 8145a6917e7c6bf738d0e136bf7f4cb424f1c4c6..5ae029fc41e5749d2bd03ca337c748a81c843b1c 100644
--- a/src/m_fixed.h
+++ b/src/m_fixed.h
@@ -38,13 +38,28 @@
 	unit used as fixed_t
 */
 
+//Max number a stat can have
+#define MAXSTAT 9
+
 typedef INT32 fixed_t;
 
 /*!
   \brief convert fixed_t into floating number
 */
-#define FIXED_TO_FLOAT(x) (((float)(x)) / ((float)FRACUNIT))
-#define FLOAT_TO_FIXED(f) (fixed_t)((f) * ((float)FRACUNIT))
+
+FUNCMATH FUNCINLINE static ATTRINLINE float FixedToFloat(fixed_t x)
+{
+	return x / (float)FRACUNIT;
+}
+
+FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FloatToFixed(float f)
+{
+	return (fixed_t)(f * FRACUNIT);
+}
+
+// for backwards compat
+#define FIXED_TO_FLOAT(x) FixedToFloat(x) // (((float)(x)) / ((float)FRACUNIT))
+#define FLOAT_TO_FIXED(f) FloatToFixed(f) // (fixed_t)((f) * ((float)FRACUNIT))
 
 
 #if defined (__WATCOMC__) && FRACBITS == 16