if(!isObject(MarcPersonalityData)) new ScriptObject(MarcPersonalityData);
function MarcPersonalityData::parseFile(%this,%file,%verbose) {
	// +======================================================================================+
	// | PARSE FILE                                                                           |
	// +======================================================================================+
	if(!isFile(%file)) {
		error("ERROR: MarcPersonalityData::parseFile() - File '"@%file@"' does not exist.");
		return 0;
	}
	if(%file !$= "add-ons/server_vore/server.cs" && fileExt(%file) !$= ".pso") {
		warn("WARNING: MarcPersonalityData::parseFile() - File '" @ %file @ "' is not encrypted; encrypting...");
		%encFile = strReplace(%file,fileExt(%file),".pso");
		%SO  = new FileObject();
		%ESO = new FileObject();
		%SO.openForRead(%file);
		%ESO.enc_openForWrite(%encFile, "MARCPERSONALITY1.0");
		while(!%SO.isEOF()) {
			%ESO.enc_writeLine(%SO.readLine());
		}
		%SO.close();
		%ESO.enc_close();
		%SO.delete();
		%ESO.delete();
		%file = %encFile;
	}
	for(%i=0;%i<%this.pCount;%i++) {
		for(%j=0;%j<%this.pDataCount[%i];%j++) %this.pData[%i@"_"@%j] = "";
		%this.p_lookUpTbl[%this.p[%i]] = "";
		%this.p[%i]                    = "";
		%this.pDataCount[%i]           = "";
	}
	%this.pCount = 0;
	echo("Parsing compiled script "@%file@".");
	%p_define = "";
	%p_expect = "";
	%SO       = new FileObject();
	if(%file !$= "add-ons/server_vore/server.cs")
		%SO.enc_openForRead(%file, "MARCPERSONALITY1.0");
	else
		%SO.openForRead(%file);

	while(!%SO.isEOF()) {
		%line++;
		if(%file $= "add-ons/server_vore/server.cs")
			%strLine = trim(%SO.readLine());
		else
			%strLine = trim(%SO.enc_readLine());

		%actionName  = "";
		%arg         = "";
		if(%strLine $= "") continue;
		if(%file $= "add-ons/server_vore/server.cs") %strLine = getSubStr(%strLine,2,strLen(%strLine));
		if(%strLine $= "[END PERSONALITY FILE]") {
			if(%verbose) echo("[Line: "@getSubStr("0000"@%line,strLen("0000"@%line)-4,4)@"] + \c2End personality file");
			break;
		}
		if(strLen(%strLine) >= 2 && getSubStr(%strLine,0,2) $= "//") {
			if(%verbose) echo("[Line: "@getSubStr("0000"@%line,strLen("0000"@%line)-4,4)@"] + \c3Comment line");
			continue;
		}
		if(getSubStr(%strLine,0,1) $= "[") {
			// Definition
			%end    = strIPos(%strLine,"]");
			%middle = strIPos(%strLine,":");
			if(%end == -1) {
				// SYNTAX ERROR
				echo("\c2"@%file SPC "Line:" SPC %line SPC "- Syntax error.");
				echo("\c1>>> Some error context, with ## on sides of error halt:");
				echo("\c2"@%strLine@"####");
				echo("\c1>>> Error report complete.\n");
				return 0;
			}
			%actionName  = getSubStr(%strLine,strIPos(%strLine,"[")+1,strLen(%strLine));
			%actionName  = getSubStr(%actionName,0,(%middle != -1 ? %middle : %end)-1);
			if(%middle != -1) {
				%arg = getSubStr(%strLine,%middle+1,strLen(%strLine));
				%arg = getSubStr(%arg,0,strIPos(%arg,"]"));
			}
			if(%verbose) echo("[Line: "@getSubStr("0000"@%line,strLen("0000"@%line)-4,4)@"] + \c4Got definition line!\n   + Type: \""@%actionName@"\"\n   + Argument: \""@%arg@"\"");
			switch$(strUpr(%actionName)) {
				case "PERSONALITY":
					if(%arg $= "") {
						echo("\c2"@%file SPC "Line: "@%line@" - Failed to declare personality without name!");
						continue;
					}
					%this.p_lookUpTbl[%arg]          = (-1+%this.pCount++);
					%this.p[%this.p_lookUpTbl[%arg]] = %arg;
					%p_define = "P_"@%this.p_lookupTbl[%arg];
					%p_expect = "_onChase::YSpeed_string_";
				case "HEADER":
					%p_define = "Header";
					%p_expect = "";
			}
			continue;
		}
		%actionName = firstWord(%strLine);
		%strLine    = removeWord(%strLine,0);
		%pNumber    = strReplace(%p_define,"P_","");
		if(%verbose) echo("[Line: "@getSubStr("0000"@%line,strLen("0000"@%line)-4,4)@"] + \c4Parsing line (Action:\""@%actionName@"\") - "@%strLine);
		if(strIPos(%p_expect,"_"@%actionName@"_") == -1) {
			echo("\c2"@%file SPC "Line: "@%line@" - Action '"@%actionName@"' not expected for '"@%p_define@"' definition.");
			continue;
		}
		switch$(%actionName) {
			case "onChase::YSpeed":
				%replace = stripChars(%strLine,"0123456789");
				%strLine = stripChars(%strLine,%replace);
				if(%strLine $= "") continue;
				%this.pData[%pNumber@"_"@(-1+%this.pDataCount[%pNumber]++)] = "onChase::YSpeed" SPC %strLine;
			case "string":
				// This personality type says it this way!
				%this.pData[%pNumber@"_"@(-1+%this.pDataCount[%pNumber]++)] = "string" SPC firstWord(%strLine) SPC removeWord(%strLine,0);
		}
	}
	if(%file $= "add-ons/server_vore/server.cs") %SO.close();
	else %SO.enc_close();

	%SO.delete();
}
function MarcPersonalityData::isPersonality(%this,%pname) {
	%pData = %this.p_lookUpTbl[%pName];
	return (%pData $= "" ? "0" : "1");
}
function MarcPersonalityData::getString(%this,%personality,%str) {
	%pData = %this.p_lookupTbl[%personality];
	if(%pData $= "") {
		error("ERROR: MarcPersonalityData::getString() - Personality "@%personality@" not found.");
		return 0;
	}
	for(%i=0;%i<%this.pDataCount[%pData];%i++) {
		%dataBlock = %this.pData[%pData@"_"@%i];
		if(firstWord(%dataBlock) !$= "string") continue;
		if(getWord(%dataBlock,1) !$= %str) continue;
		return removeWord(removeWord(%dataBlock,0),0);
	}
	return "";
}
function MarcPersonalityData::getChaseY(%this,%personality) {
	%pData = %this.p_lookupTbl[%personality];
	if(%pData $= "") {
		error("ERROR: MarcPersonalityData::getChaseY() - Personality "@%personality@" not found.");
		return 0;
	}
	for(%i=0;%i<%this.pDataCount[%pData];%i++) {
		%dataBlock = %this.pData[%pData@"_"@%i];
		if(firstWord(%dataBlock) !$= "onChase::YSpeed") continue;
		return removeWord(%dataBlock,0);
	}
	return "";
}
function MarcPersonalityData::getStringCount(%this,%personality,%prefix) {
	%pData = %this.p_lookupTbl[%personality];
	if(%pData $= "") {
		error("ERROR: MarcPersonalityData::getStringCount() - Personality "@%personality@" not found.");
		return 0;
	}
	for(%i=0;%i<%this.pDataCount[%pData];%i++) {
		%dataBlock = %this.pData[%pData@"_"@%i];
		if(firstWord(%dataBlock) !$= "string") continue;
		if(strLen(getWord(%dataBlock,1)) != strLen(%prefix)+1) continue;
		if(strIPos(getWord(%dataBlock,1),%prefix) != 0) continue;
		%count = (-1+%caught++);
	}
	return (%count $= "" ? "0" : %count);
}
function MarcPersonalityData::getRandomString(%this,%personality,%prefix) {
	%pData = %this.p_lookupTbl[%personality];
	if(%pData $= "") {
		error("ERROR: MarcPersonalityData::getRandomString() - Personality "@%personality@" not found.");
		return 0;
	}
	%r = getRandom(0,%this.getStringCount(%personality,%prefix));
	for(%i=0;%i<%this.pDataCount[%pData];%i++) {
		%dataBlock = %this.pData[%pData@"_"@%i];
		if(firstWord(%dataBlock) !$= "string") continue;
		if(strLen(getWord(%dataBlock,1)) != strLen(%prefix)+1) continue;
		if(strIPos(getWord(%dataBlock,1),%prefix) != 0) continue;
		%count = (-1+%caught++);
		if(%count != %r) continue;
		return removeWord(removeWord(%dataBlock,0),0);
	}
	return "";
}
function MarcPersonalityData::dumpPersonality(%this,%personality) {
	%pData = %this.p_lookupTbl[%personality];
	if(%pData $= "") {
		error("ERROR: MarcPersonalityData::dumpPersonality() - Personality "@%personality@" not found.");
		return 0;
	}
	for(%i=0;%i<%this.pDataCount[%pData];%i++) {
		%dataBlock = %this.pData[%pData@"_"@%i];
		if(firstWord(%dataBlock) !$= "string") continue;
		%str = getWord(%dataBlock,1);
		if(strLen(%str) > %longestStr) %longestStr = strLen(%str);
	}
	%longestStr += 3;
	for(%i=0;%i<%longestStr;%i++) %strTbl = %strTbl SPC "";
	for(%i=0;%i<%this.pDataCount[%pData];%i++) {
		%dataBlock = %this.pData[%pData@"_"@%i];
		if(firstWord(%dataBlock) $= "string") {
			%string = getWord(%dataBlock,1)@%strTbl;
			%string = getSubStr(%string,0,%longestStr);
			echo("==] \c2"@getWord(%dataBlock,0) SPC "\c4"@%string SPC "\c0"@removeWord(removeWord(%dataBlock,0),0));
			continue;
		}
		echo("==] \c2"@getWord(%dataBlock,0) SPC "\c4"@removeWord(%dataBlock,0));
	}
}