So, let's start at the beginning. First, open the file PlayerEntity.h and go to line 1029 and replace that line with the following:
Code: Select all
NSString *OODisplayStringFromLegalStatus(unsigned legalStatus);
Now open the NSStringOOExtensions.h file and add this at line 61:
Code: Select all
- (NSComparisonResult)oo_compareNumerically:(NSString *)str;
Now open the OOConstToString.h file and add this at line 106:
Code: Select all
NSString *OODisplayCustomStringFromDescriptionsArray(NSString *inputNumArray, NSString *inputStringArray, unsigned inputNum, NSString *context);
This takes care of the header files. Now, open the NSStringOOExtensions.m file and add the following at line 151:
Code: Select all
- (NSComparisonResult)oo_compareNumerically:(NSString *)str
{
NSNumber * num1 = [NSNumber numberWithInt:[self intValue]];
NSNumber * num2 = [NSNumber numberWithInt:[str intValue]];
return [num1 compare:num2];
}
Now open the OOConstToString.m file and go to line 470. Insert the following here (do not replace anything yet, just insert this function):
Code: Select all
NSString *OODisplayCustomStringFromDescriptionsArray(NSString *inputNumArray, NSString *inputStringArray, unsigned inputNum, NSString *context)
{
NSArray *stringArray = nil;
NSArray *numArray = nil;
NSMutableArray *mutableNumArray = [[NSMutableArray alloc] init];
NSArray *sortedNumArray = nil;
NSMutableDictionary *stringArrayDict = [[NSMutableDictionary alloc] init];
NSString *numString;
NSString *textString;
unsigned i;
int numInt;
BOOL customStringInvalid;
NSString *logKey;
stringArray = [[UNIVERSE descriptions] oo_arrayForKey:inputStringArray];
numArray = [[UNIVERSE descriptions] oo_arrayForKey:inputNumArray];
customStringInvalid = NO;
numInt = 0;
logKey = @"_default";
if ([context isEqualToString:@"ratings"]) logKey = @"new.ratings.error";
if ([context isEqualToString:@"legal_status"]) logKey = @"new.legal.status.error";
for (i = 0; i < [numArray count]; ++i)
{
textString = [NSString stringWithFormat:@"%u", [numArray oo_intAtIndex:i]];
numInt = [textString integerValue];
if (numInt < 0)
{
customStringInvalid = YES;
OOLog(logKey, @"'%@' array in descriptions.plist contains a negative value - reverting to original system.", inputNumArray);
break;
}
}
for (i = 0; i < [numArray count]; ++i)
{
textString = [NSString stringWithFormat:@"%u", [numArray oo_intAtIndex:i]];
[mutableNumArray addObject:textString];
}
sortedNumArray = [mutableNumArray sortedArrayUsingSelector:@selector(oo_compareNumerically:)];
if ([stringArray count] != [sortedNumArray count] && !customStringInvalid)
{
customStringInvalid = YES;
OOLog(logKey, @"'%@' and '%@' array size in descriptions.plist not equal - reverting to original system.", inputNumArray, inputStringArray);
}
if ([sortedNumArray oo_unsignedIntAtIndex:0] != 0 && !customStringInvalid)
{
customStringInvalid = YES;
OOLog(logKey, @"'%@' array in descriptions.plist does not start at 0 - reverting to original system.", inputNumArray);
}
if (!customStringInvalid)
{
for (i = 0; i < [mutableNumArray count]; ++i)
{
numString = [NSString stringWithFormat:@"%u", [mutableNumArray oo_unsignedIntAtIndex:i]];
textString = [stringArray oo_stringAtIndex:i];
[stringArrayDict setObject:textString forKey:numString];
}
for (i = 0; i < [sortedNumArray count]; ++i)
{
if (inputNum < [sortedNumArray oo_unsignedIntAtIndex:i])
{
numString = [NSString stringWithFormat:@"%u", [sortedNumArray oo_unsignedIntAtIndex:i-1]];
if ([stringArrayDict objectForKey:numString] != nil)
{
return [stringArrayDict objectForKey:numString];
}
else
{
customStringInvalid = YES;
OOLog(logKey, @"'nil' value returned when trying to display rating status - reverting to original system.");
break;
}
}
}
}
if (customStringInvalid)
{
if ([context isEqualToString:@"ratings"])
{
enum { kRatingCount = 9 };
const unsigned killThresholds[kRatingCount - 1] =
{
0x0008,
0x0010,
0x0020,
0x0040,
0x0080,
0x0200,
0x0A00,
0x1900
};
NSString *eliteRating = [NSString stringWithUTF8String:"★★★ E L I T E ★★★"];
NSString *deadlyRating = [NSString stringWithUTF8String:"☆ Deadly ☆"];
stringArray = [NSArray arrayWithObjects:@"Harmless",@"Mostly Harmless",@"Poor",@"Average",@"Above Average",@"Competent",@"Dangerous",deadlyRating,eliteRating,nil];
for (i = 0; i < kRatingCount - 1; ++i)
{
if (inputNum < killThresholds[i]) return [stringArray oo_stringAtIndex:i];
}
return [stringArray oo_stringAtIndex:kRatingCount - 1];
}
if ([context isEqualToString:@"legal_status"])
{
enum { kStatusCount = 3 };
const int statusThresholds[kStatusCount - 1] =
{
1,
51
};
stringArray = [NSArray arrayWithObjects:@"Clean",@"Offender",@"Fugitive",nil];
for (i = 0; i != kStatusCount - 1; ++i)
{
if (inputNum < statusThresholds[i]) return [stringArray oo_stringAtIndex:i];
}
return [stringArray oo_stringAtIndex:kStatusCount - 1];
}
}
i = [sortedNumArray count] - 1;
numString = [NSString stringWithFormat:@"%u", [sortedNumArray oo_unsignedIntAtIndex:i]];
return [stringArrayDict objectForKey:numString];
}
Now, go to line 607 and replace the section/function there with the following:
Code: Select all
NSString *OODisplayRatingStringFromKillCount(unsigned kills)
{
NSString *killsArrayKey = @"oolite_rating_kills";
NSString *ratingsArrayKey = @"oolite_rating_names";
NSString *contextType = @"ratings";
return [NSString stringWithFormat:@"%@", OODisplayCustomStringFromDescriptionsArray(killsArrayKey, ratingsArrayKey, kills, contextType)];
}
Go down to line 624 and the replace the section/function there with the following:
Code: Select all
NSString *OODisplayStringFromLegalStatus(unsigned legalStatus)
{
NSString *bountyArrayKey = @"oolite_legal_status_bounty";
NSString *statusArrayKey = @"oolite_legal_status_names";
NSString *contextType = @"legal_status";
return [NSString stringWithFormat:@"%@", OODisplayCustomStringFromDescriptionsArray(bountyArrayKey, statusArrayKey, legalStatus, contextType)];
}
This takes care of the source files. Now open up the descriptions.plist file in the resources and insert the following four arrays:
Code: Select all
"oolite_rating_kills" =
(
0,
8,
15,
32,
64,
128,
512,
2560,
6400
);
"oolite_rating_names" =
(
"Harmless",
"Mostly Harmless",
"Poor",
"Average",
"Above Average",
"Competent",
"Dangerous",
"☆ Deadly ☆",
"★★★ E L I T E ★★★"
);
"oolite_legal_status_bounty" =
(
0,
1,
51
);
"oolite_legal_status_names" =
(
"Clean",
"Offender",
"Fugitive"
);
Finally, open up logcontrol.plist and add the following two lines:
Code: Select all
new.ratings.error = yes;
new.legal.status.error = yes;
This should now provide a fully customisable ratings and legal status system. Any errors will be picked up, logged accordingly and will revert to the original systems. The only thing these new systems are dependent on, is making sure that the numeric value that corresponds to the text value are at the same positions on the arrays. But numerical order is not required, and it doesn't matter if the numeric value is considered to be string or integer, as the code deals with this accordingly...
...Now, I'm hoping this takes care of everything, but I fear there's still something I've forgotten about (although I can't figure out what)...