Adds HP related fields to core data.
Implements hitDieForSize and hitPointsDescription in Monster. Adds tests.
This commit is contained in:
@@ -17,6 +17,12 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern NSString* const kMonsterSizeTiny;
|
||||
extern NSString* const kMonsterSizeSmall;
|
||||
extern NSString* const kMonsterSizeMedium;
|
||||
extern NSString* const kMonsterSizeLarge;
|
||||
extern NSString* const kMonsterSizeHuge;
|
||||
extern NSString* const kMonsterSizeGargantuan;
|
||||
|
||||
extern const int kArmorClassUnarmored;
|
||||
extern const int kArmorClassMageArmor;
|
||||
@@ -54,7 +60,6 @@ extern NSString* const kArmorNameOther;
|
||||
|
||||
@interface Monster : NSManagedObject
|
||||
|
||||
@property NSString *hpText;
|
||||
@property NSString *speed;
|
||||
@property NSString *burrowSpeed;
|
||||
@property NSString *climbSpeed;
|
||||
@@ -71,12 +76,10 @@ extern NSString* const kArmorNameOther;
|
||||
@property NSString *understandsBut;
|
||||
|
||||
@property int naturalArmorBonus;
|
||||
@property int hitDice;
|
||||
@property int customProficiencyBonus;
|
||||
// Shouldn't this be a BOOL?
|
||||
@property int telepathy;
|
||||
|
||||
@property BOOL customHP;
|
||||
@property BOOL hover;
|
||||
@property BOOL customSpeed;
|
||||
@property BOOL isBlind;
|
||||
|
||||
@@ -17,15 +17,12 @@
|
||||
@synthesize challengeRating;
|
||||
@synthesize climbSpeed;
|
||||
@synthesize customChallengeRating;
|
||||
@synthesize customHP;
|
||||
@synthesize customProficiencyBonus;
|
||||
@synthesize customSpeed;
|
||||
@synthesize customSpeedDescription;
|
||||
@synthesize darkvisionDistance;
|
||||
@synthesize flySpeed;
|
||||
@synthesize hitDice;
|
||||
@synthesize hover;
|
||||
@synthesize hpText;
|
||||
@synthesize isBlind;
|
||||
@synthesize naturalArmorBonus;
|
||||
@synthesize speed;
|
||||
@@ -66,12 +63,34 @@ NSString* const kArmorNameChainMail = @"chain mail";
|
||||
NSString* const kArmorNameSplintMail = @"splint";
|
||||
NSString* const kArmorNamePlateMail = @"plate";
|
||||
NSString* const kArmorNameOther = @"other";
|
||||
|
||||
NSString* const kMonsterSizeTiny = @"tiny";
|
||||
NSString* const kMonsterSizeSmall = @"small";
|
||||
NSString* const kMonsterSizeMedium = @"medium";
|
||||
NSString* const kMonsterSizeLarge = @"large";
|
||||
NSString* const kMonsterSizeHuge = @"huge";
|
||||
NSString* const kMonsterSizeGargantuan = @"gargantuan";
|
||||
|
||||
+(int)abilityModifierForScore: (int)score {
|
||||
return (int)floor((score - 10) / 2.0);
|
||||
}
|
||||
|
||||
+(int)hitDieForSize: (NSString*)size{
|
||||
@throw [[NSException alloc] initWithName:@"unimplemented" reason:@"Method not implemented." userInfo:nil];
|
||||
if ([kMonsterSizeTiny isEqualToString:size]) {
|
||||
return 4;
|
||||
} else if ([kMonsterSizeSmall isEqualToString:size]) {
|
||||
return 6;
|
||||
} else if ([kMonsterSizeMedium isEqualToString:size]) {
|
||||
return 8;
|
||||
} else if ([kMonsterSizeLarge isEqualToString:size]) {
|
||||
return 10;
|
||||
} else if ([kMonsterSizeHuge isEqualToString:size]) {
|
||||
return 12;
|
||||
} else if ([kMonsterSizeGargantuan isEqualToString:size]) {
|
||||
return 20;
|
||||
} else {
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
-(id)init {
|
||||
@@ -98,6 +117,8 @@ NSString* const kArmorNameOther = @"other";
|
||||
self.size = [JSONHelper readStringFromDictionary:jsonRoot forKey:@"size" withDefaultValue:@""];
|
||||
self.type = [JSONHelper readStringFromDictionary:jsonRoot forKey:@"type" withDefaultValue:@""];
|
||||
self.subtype = [JSONHelper readStringFromDictionary:jsonRoot forKey:@"tag" withDefaultValue:@""];
|
||||
self.hpText = [JSONHelper readStringFromDictionary:jsonRoot forKey:@"hpText" withDefaultValue:@""];
|
||||
|
||||
self.alignment = [JSONHelper readStringFromDictionary:jsonRoot forKey:@"alignment" withDefaultValue:@""];
|
||||
self.armorName = [JSONHelper readStringFromDictionary:jsonRoot forKey:@"armorName" withDefaultValue:@""];
|
||||
self.otherArmorDescription = [JSONHelper readStringFromDictionary:jsonRoot forKey:@"otherArmorDesc" withDefaultValue:@""];
|
||||
@@ -108,6 +129,9 @@ NSString* const kArmorNameOther = @"other";
|
||||
self.wisdomScore = [JSONHelper readIntFromDictionary:jsonRoot forKey:@"wisPoints" withDefaultValue:0];
|
||||
self.charismaScore = [JSONHelper readIntFromDictionary:jsonRoot forKey:@"chaPoints" withDefaultValue:0];
|
||||
self.shieldBonus = [JSONHelper readIntFromDictionary:jsonRoot forKey:@"shieldBonus" withDefaultValue:0];
|
||||
self.hitDice = [JSONHelper readIntFromDictionary:jsonRoot forKey:@"hitDice" withDefaultValue:0];
|
||||
|
||||
self.customHP = [JSONHelper readBoolFromDictionary:jsonRoot forKey:@"customHP" withDefaultValue:NO];
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -251,7 +275,15 @@ NSString* const kArmorNameOther = @"other";
|
||||
|
||||
//getHitPoints
|
||||
-(NSString*)hitPointsDescription {
|
||||
@throw [[NSException alloc] initWithName:@"unimplemented" reason:@"Method not implemented." userInfo:nil];
|
||||
if (self.customHP) {
|
||||
return self.hpText;
|
||||
} else {
|
||||
int dieSize = [Monster hitDieForSize:self.size];
|
||||
int conMod = self.constitutionModifier;
|
||||
int hpTotal = (int)MAX(1, ceil(dieSize + conMod + (self.hitDice - 1) * ((dieSize + 1) / 2.0 + conMod)));
|
||||
int conBonus = conMod * self.hitDice;
|
||||
return [NSString stringWithFormat:@"%d (%dd%d%+d)", hpTotal, self.hitDice, dieSize, conBonus];
|
||||
}
|
||||
}
|
||||
|
||||
//getSpeedText
|
||||
@@ -450,6 +482,9 @@ NSString* const kArmorNameOther = @"other";
|
||||
self.armorName = monster.armorName;
|
||||
self.otherArmorDescription = monster.otherArmorDescription;
|
||||
self.shieldBonus = monster.shieldBonus;
|
||||
self.customHP = monster.customHP;
|
||||
self.hitDice = monster.hitDice;
|
||||
self.hpText = monster.hpText;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="16119" systemVersion="19G2021" minimumToolsVersion="Automatic" sourceLanguage="Objective-C" usedWithCloudKit="YES" userDefinedModelVersionIdentifier="">
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="17192" systemVersion="19G2021" minimumToolsVersion="Automatic" sourceLanguage="Objective-C" usedWithCloudKit="YES" userDefinedModelVersionIdentifier="">
|
||||
<entity name="Monster" representedClassName="Monster" syncable="YES" codeGenerationType="category">
|
||||
<attribute name="alignment" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="armorName" optional="YES" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="charismaScore" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="constitutionScore" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="customHP" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="dexterityScore" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="hitDice" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="hpText" optional="YES" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="intelligenceScore" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="name" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="otherArmorDescription" optional="YES" attributeType="String" defaultValueString=""/>
|
||||
@@ -17,6 +20,6 @@
|
||||
<attribute name="wisdomScore" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="Monster" positionX="-63" positionY="-18" width="128" height="253"/>
|
||||
<element name="Monster" positionX="-63" positionY="-18" width="128" height="298"/>
|
||||
</elements>
|
||||
</model>
|
||||
@@ -25,7 +25,7 @@
|
||||
- (void)setUp {
|
||||
_context = nil;
|
||||
_monster = [[Monster alloc] initWithContext:_context];
|
||||
_jsonString = @"{\"name\":\"Acolyte\",\"size\":\"medium\",\"type\":\"humanoid\",\"tag\":\"any race\",\"alignment\":\"any alignment\",\"strPoints\":8,\"dexPoints\":10,\"conPoints\":12,\"intPoints\":14,\"wisPoints\":16,\"chaPoints\":18,\"armorName\":\"none\",\"otherArmorDesc\":\"10\",\"shieldBonus\":2}";
|
||||
_jsonString = @"{\"name\":\"Acolyte\",\"size\":\"medium\",\"type\":\"humanoid\",\"tag\":\"any race\",\"alignment\":\"any alignment\",\"strPoints\":8,\"dexPoints\":10,\"conPoints\":12,\"intPoints\":14,\"wisPoints\":16,\"chaPoints\":18,\"armorName\":\"none\",\"otherArmorDesc\":\"10\",\"shieldBonus\":2,\"hitDice\":3,\"customHP\":true,\"hpText\":\"1234 (1d1+magic)\"}";
|
||||
_jsonData = [_jsonString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
@@ -49,7 +49,9 @@
|
||||
XCTAssertEqualObjects(@"", _monster.armorName);
|
||||
XCTAssertEqualObjects(@"", _monster.otherArmorDescription);
|
||||
XCTAssertEqual(0, _monster.shieldBonus);
|
||||
}
|
||||
XCTAssertEqual(NO, _monster.customHP);
|
||||
XCTAssertEqual(0, _monster.hitDice);
|
||||
XCTAssertEqualObjects(@"", _monster.hpText);}
|
||||
|
||||
- (void)testInitWithJSONString {
|
||||
_monster = [[Monster alloc] initWithJSONString:_jsonString andContext:_context];
|
||||
@@ -69,6 +71,9 @@
|
||||
XCTAssertEqualObjects(@"none", _monster.armorName);
|
||||
XCTAssertEqualObjects(@"10", _monster.otherArmorDescription);
|
||||
XCTAssertEqual(2, _monster.shieldBonus);
|
||||
XCTAssertEqual(YES, _monster.customHP);
|
||||
XCTAssertEqual(3, _monster.hitDice);
|
||||
XCTAssertEqualObjects(@"1234 (1d1+magic)", _monster.hpText);
|
||||
}
|
||||
|
||||
- (void)testInitWithEmptyJSONString {
|
||||
@@ -89,7 +94,11 @@
|
||||
XCTAssertEqualObjects(@"", _monster.armorName);
|
||||
XCTAssertEqualObjects(@"", _monster.otherArmorDescription);
|
||||
XCTAssertEqual(0, _monster.shieldBonus);
|
||||
XCTAssertEqual(NO, _monster.customHP);
|
||||
XCTAssertEqual(0, _monster.hitDice);
|
||||
XCTAssertEqualObjects(@"", _monster.hpText);
|
||||
}
|
||||
|
||||
- (void)testInitWithJSONData {
|
||||
_monster = [[Monster alloc] initWithJSONData:_jsonData andContext:_context];
|
||||
|
||||
@@ -108,6 +117,9 @@
|
||||
XCTAssertEqualObjects(@"none", _monster.armorName);
|
||||
XCTAssertEqualObjects(@"10", _monster.otherArmorDescription);
|
||||
XCTAssertEqual(2, _monster.shieldBonus);
|
||||
XCTAssertEqual(YES, _monster.customHP);
|
||||
XCTAssertEqual(3, _monster.hitDice);
|
||||
XCTAssertEqualObjects(@"1234 (1d1+magic)", _monster.hpText);
|
||||
}
|
||||
|
||||
- (void)testNameGetterAndSetter {
|
||||
@@ -382,4 +394,46 @@
|
||||
XCTAssertEqualObjects(@"green", _monster.otherArmorDescription);
|
||||
}
|
||||
|
||||
- (void)testHitDieForSizeReturnsExpectedValuesForKnownSizes {
|
||||
|
||||
}
|
||||
|
||||
- (void)testHitDieForSizeReutnrsEightForUnknownSizes {
|
||||
XCTAssertEqual(4, [Monster hitDieForSize:kMonsterSizeTiny]);
|
||||
XCTAssertEqual(6, [Monster hitDieForSize:kMonsterSizeSmall]);
|
||||
XCTAssertEqual(8, [Monster hitDieForSize:kMonsterSizeMedium]);
|
||||
XCTAssertEqual(10, [Monster hitDieForSize:kMonsterSizeLarge]);
|
||||
XCTAssertEqual(12, [Monster hitDieForSize:kMonsterSizeHuge]);
|
||||
XCTAssertEqual(20, [Monster hitDieForSize:kMonsterSizeGargantuan]);
|
||||
}
|
||||
|
||||
- (void)testCustomHPGetterAndSetter {
|
||||
XCTAssertEqual(8, [Monster hitDieForSize:nil]);
|
||||
XCTAssertEqual(8, [Monster hitDieForSize:@""]);
|
||||
XCTAssertEqual(8, [Monster hitDieForSize:@"unknown size"]);
|
||||
}
|
||||
|
||||
- (void)testHitDiceGetterAndSetter {
|
||||
_monster.hitDice = 9;
|
||||
XCTAssertEqual(9, _monster.hitDice);
|
||||
}
|
||||
|
||||
- (void)testHPTextGetterAndSetter {
|
||||
_monster.hpText = @"This is my HP.";
|
||||
XCTAssertEqualObjects(@"This is my HP.", _monster.hpText);
|
||||
}
|
||||
|
||||
- (void)testHitPointsDescriptionWithCustomHP {
|
||||
_monster = [[Monster alloc] initWithJSONString:_jsonString andContext:_context];
|
||||
_monster.customHP = YES;
|
||||
XCTAssertEqualObjects(@"1234 (1d1+magic)", _monster.hitPointsDescription);
|
||||
}
|
||||
|
||||
- (void)testHitPointsDescriptionWithCalculatedHP {
|
||||
_monster = [[Monster alloc] initWithJSONString:_jsonString andContext:_context];
|
||||
_monster.customHP = NO;
|
||||
XCTAssertEqualObjects(@"20 (3d8+3)", _monster.hitPointsDescription);
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user