2 // HMKCShipObject+Extensions.m
5 // Created by Hori,Masaki on 2014/06/08.
6 // Copyright (c) 2014年 Hori,Masaki. All rights reserved.
9 #import "HMKCShipObject+Extensions.h"
10 #import "HMKCMasterShipObject.h"
11 #import "HMKCMasterSType.h"
13 #import "HMKCMasterSlotItemObject.h"
14 #import "HMKCSlotItemObject+Extensions.h"
16 #import "HMServerDataStore.h"
17 #import "HMTemporaryDataStore.h"
18 #import "HMUserDefaults.h"
21 static NSArray *shortSTypeNames = nil;
22 static NSArray *levelUpExps = nil;
24 @implementation HMKCShipObject (Extensions)
28 static dispatch_once_t onceToken;
29 dispatch_once(&onceToken, ^{
30 NSBundle *mainBundle = [NSBundle mainBundle];
31 NSURL *url = [mainBundle URLForResource:@"STypeShortName" withExtension:@"plist"];
32 NSArray *array = [[NSArray alloc] initWithContentsOfURL:url];
34 NSLog(@"Can not load STypeShortName.plist.");
36 shortSTypeNames = [array copy];
38 url = [mainBundle URLForResource:@"LevelUpExp" withExtension:@"plist"];
39 array = [[NSArray alloc] initWithContentsOfURL:url];
41 NSLog(@"Can not load LevelUpExp.plist.");
43 levelUpExps = [array copy];
48 + (NSSet *)keyPathsForValuesAffectingIsMaxKaryoku
50 return [NSSet setWithObjects:@"karyoku_1", @"kyouka_0", nil];
52 - (NSNumber *)isMaxKaryoku
54 [self willAccessValueForKey:@"master_ship"];
55 [self willAccessValueForKey:@"karyoku_1"];
56 [self willAccessValueForKey:@"kyouka_0"];
57 NSInteger defaultValue = [self.master_ship.houg_0 integerValue];
58 NSInteger maxValue = [self.karyoku_1 integerValue];
59 NSInteger growth = [self.kyouka_0 integerValue];
60 [self didAccessValueForKey:@"kyouka_0"];
61 [self didAccessValueForKey:@"karyoku_1"];
62 [self didAccessValueForKey:@"master_ship"];
64 return @(defaultValue + growth >= maxValue);
67 + (NSSet *)keyPathsForValuesAffectingIsMaxRaisou
69 return [NSSet setWithObjects:@"raisou_1", @"kyouka_1", nil];
71 - (NSNumber *)isMaxRaisou
73 [self willAccessValueForKey:@"master_ship"];
74 [self willAccessValueForKey:@"raisou_1"];
75 [self willAccessValueForKey:@"kyouka_1"];
76 NSInteger defaultValue = [self.master_ship.raig_0 integerValue];
77 NSInteger maxValue = [self.raisou_1 integerValue];
78 NSInteger growth = [self.kyouka_1 integerValue];
79 [self didAccessValueForKey:@"kyouka_1"];
80 [self didAccessValueForKey:@"raisou_1"];
81 [self didAccessValueForKey:@"master_ship"];
83 return @(defaultValue + growth >= maxValue);
86 + (NSSet *)keyPathsForValuesAffectingIsMaxTaiku
88 return [NSSet setWithObjects:@"taiku_1", @"kyouka_2", nil];
90 - (NSNumber *)isMaxTaiku
92 [self willAccessValueForKey:@"master_ship"];
93 [self willAccessValueForKey:@"taiku_1"];
94 [self willAccessValueForKey:@"kyouka_2"];
95 NSInteger defaultValue = [self.master_ship.tyku_0 integerValue];
96 NSInteger maxValue = [self.taiku_1 integerValue];
97 NSInteger growth = [self.kyouka_2 integerValue];
98 [self didAccessValueForKey:@"kyouka_2"];
99 [self didAccessValueForKey:@"taiku_1"];
100 [self didAccessValueForKey:@"master_ship"];
102 return @(defaultValue + growth >= maxValue);
105 + (NSSet *)keyPathsForValuesAffectingIsMaxSoukou
107 return [NSSet setWithObjects:@"soukou_1", @"kyouka_3", nil];
109 - (NSNumber *)isMaxSoukou
111 [self willAccessValueForKey:@"master_ship"];
112 [self willAccessValueForKey:@"soukou_1"];
113 [self willAccessValueForKey:@"kyouka_3"];
114 NSInteger defaultValue = [self.master_ship.souk_0 integerValue];
115 NSInteger maxValue = [self.soukou_1 integerValue];
116 NSInteger growth = [self.kyouka_3 integerValue];
117 [self didAccessValueForKey:@"kyouka_3"];
118 [self didAccessValueForKey:@"soukou_1"];
119 [self didAccessValueForKey:@"master_ship"];
121 return @(defaultValue + growth >= maxValue);
124 + (NSSet *)keyPathsForValuesAffectingIsMaxLucky
126 return [NSSet setWithObjects:@"lucky_1", @"kyouka_4", nil];
128 - (NSNumber *)isMaxLucky
130 [self willAccessValueForKey:@"master_ship"];
131 [self willAccessValueForKey:@"lucky_1"];
132 [self willAccessValueForKey:@"kyouka_4"];
133 NSInteger defaultValue = [self.master_ship.luck_0 integerValue];
134 NSInteger maxValue = [self.lucky_1 integerValue];
135 NSInteger growth = [self.kyouka_4 integerValue];
136 [self didAccessValueForKey:@"kyouka_4"];
137 [self didAccessValueForKey:@"lucky_1"];
138 [self didAccessValueForKey:@"master_ship"];
140 return @(defaultValue + growth >= maxValue);
143 + (NSSet *)keyPathsForValuesAffectingName
145 return [NSSet setWithObjects:@"ship_id", nil];
149 return [self.master_ship valueForKey:@"name"];
152 + (NSSet *)keyPathsForValuesAffectingShortTypeName
154 return [NSSet setWithObjects:@"ship_id", nil];
156 - (NSString *)shortTypeName
158 [self willAccessValueForKey:@"master_ship"];
159 NSNumber *idValue = self.master_ship.stype.id;
160 [self didAccessValueForKey:@"master_ship"];
161 if(!idValue || [idValue isKindOfClass:[NSNull class]]) return nil;
163 if([shortSTypeNames count] < [idValue integerValue]) return nil;
165 return shortSTypeNames[[idValue integerValue] - 1];
168 + (NSSet *)keyPathsForValuesAffectingNext
170 return [NSSet setWithObjects:@"exp", nil];
174 [self willAccessValueForKey:@"lv"];
175 id lvValue = self.lv;
176 [self didAccessValueForKey:@"lv"];
177 [self willAccessValueForKey:@"exp"];
178 id expValue = self.exp;
179 [self didAccessValueForKey:@"exp"];
181 NSUInteger currentLevel = [lvValue integerValue];
182 if(currentLevel >= [levelUpExps count]) {
185 if(currentLevel == 99) return nil;
187 NSUInteger nextExp = [[levelUpExps objectAtIndex:currentLevel] integerValue];
188 if(currentLevel > 99) {
191 return @(nextExp - [expValue integerValue]);
194 + (NSSet *)keyPathsForValuesAffectingStatus
196 return [NSSet setWithObjects:@"nowhp", @"maxph", nil];
200 [self willAccessValueForKey:@"maxhp"];
201 [self willAccessValueForKey:@"nowhp"];
202 NSInteger maxhp = [self.maxhp integerValue];
203 CGFloat nowhp = [self.nowhp integerValue];
204 [self didAccessValueForKey:@"nowhp"];
205 [self didAccessValueForKey:@"maxhp"];
207 CGFloat status = nowhp / maxhp;
221 + (NSSet *)keyPathsForValuesAffectingStatusColor
223 return [NSSet setWithObjects:@"status", nil];
225 - (NSColor *)statusColor
227 [self willAccessValueForKey:@"maxhp"];
228 [self willAccessValueForKey:@"nowhp"];
229 NSInteger maxhp = [self.maxhp integerValue];
230 CGFloat nowhp = [self.nowhp integerValue];
231 [self didAccessValueForKey:@"nowhp"];
232 [self didAccessValueForKey:@"maxhp"];
234 CGFloat status = nowhp / maxhp;
236 return [NSColor redColor];
239 return [NSColor orangeColor];
242 return [NSColor yellowColor];
245 return [NSColor controlTextColor];
248 + (NSSet *)keyPathsForValuesAffectingConditionColor
250 return [NSSet setWithObjects:@"cond", nil];
252 - (NSColor *)conditionColor
254 return [NSColor controlTextColor];
257 - (NSColor *)planColor
259 if(!HMStandardDefaults.showsPlanColor) return [NSColor controlTextColor];
261 [self willAccessValueForKey:@"sally_area"];
262 NSInteger planType = [self.sally_area integerValue];
263 [self didAccessValueForKey:@"sally_area"];
264 if(planType == 1) return HMStandardDefaults.plan01Color;
265 if(planType == 2) return HMStandardDefaults.plan02Color;
266 if(planType == 3) return HMStandardDefaults.plan03Color;
267 if(planType == 4) return HMStandardDefaults.plan04Color;
268 if(planType == 5) return HMStandardDefaults.plan05Color;
269 if(planType == 6) return HMStandardDefaults.plan06Color;
270 return [NSColor controlTextColor];
274 - (NSNumber *)maxFuel
276 [self willAccessValueForKey:@"master_ship"];
277 NSNumber *number = self.master_ship.fuel_max;
278 [self didAccessValueForKey:@"master_ship"];
281 - (NSNumber *)maxBull
283 [self willAccessValueForKey:@"master_ship"];
284 NSNumber *number = self.master_ship.bull_max;
285 [self didAccessValueForKey:@"master_ship"];
289 - (NSNumber *)upgradeLevel
291 [self willAccessValueForKey:@"master_ship"];
292 NSNumber *number = self.master_ship.afterlv;
293 [self didAccessValueForKey:@"master_ship"];
296 + (NSSet *)keyPathsForValuesAffectingUpgradeExp
298 return [NSSet setWithObjects:@"exp", nil];
300 - (NSNumber *)upgradeExp
302 NSInteger upgradeLevtl = [self.upgradeLevel integerValue];
303 if(upgradeLevtl <= 0) return nil;
305 NSInteger upgradeExp = [[levelUpExps objectAtIndex:upgradeLevtl - 1] integerValue];
306 NSInteger exp = [self.exp integerValue];
311 return @(upgradeExp);
314 - (NSNumber *)totalEquipment
317 [self willAccessValueForKey:@"master_ship"];
318 total += self.master_ship.maxeq_0.integerValue;
319 total += self.master_ship.maxeq_1.integerValue;
320 total += self.master_ship.maxeq_2.integerValue;
321 total += self.master_ship.maxeq_3.integerValue;
322 total += self.master_ship.maxeq_4.integerValue;
323 [self didAccessValueForKey:@"master_ship"];
327 + (NSSet *)keyPathsForValuesAffectingSeiku
329 return [NSSet setWithObjects:
330 @"slot_0", @"slot_1", @"slot_2", @"slot_3", @"slot_4",
331 @"onslot_0", @"onslot_1", @"onslot_2", @"onslot_3", @"onslot_4",
335 - (HMKCSlotItemObject *)slotItemAtIndex:(NSUInteger)index
337 HMServerDataStore *store = [HMServerDataStore defaultManager];
339 NSString *key = [NSString stringWithFormat:@"slot_%ld", index];
340 NSNumber *itemId = [self valueForKey:key];
341 if(itemId.integerValue == -1) return nil;
342 NSError *error = nil;
343 NSArray *array = [store objectsWithEntityName:@"SlotItem"
345 predicateFormat:@"id = %@", itemId];
346 if(array.count == 0) return nil;
347 HMKCSlotItemObject *slotItem = array[0];
352 NSArray *effectiveTypes = @[@6, @7, @8, @11];
353 __block NSInteger totalSeiku = 0;
354 for(NSInteger i = 0; i < 5; i++) {
355 HMKCSlotItemObject *slotItem = [self slotItemAtIndex:i];
356 HMKCMasterSlotItemObject *master = slotItem.master_slotItem;
357 NSNumber *type2 = master.type_2;
358 if(![effectiveTypes containsObject:type2]) {
362 NSString *key = [NSString stringWithFormat:@"onslot_%ld", i];
363 NSNumber *itemCountValue = [self valueForKey:key];
364 NSNumber *taikuValue = master.tyku;
365 NSInteger itemCount = [itemCountValue integerValue];
366 NSInteger taiku = [taikuValue integerValue];
367 if(itemCount && taiku) {
368 totalSeiku += floor(taiku * sqrt(itemCount));
372 return @(totalSeiku);
374 - (NSNumber *)extraSeiku
376 NSArray *fighterTypes = @[@6];
377 NSArray *bomberTypes = @[@7];
378 NSArray *attackerTypes = @[@8];
379 NSArray *floatplaneBomberTypes = @[@11];
380 NSArray *floatplaneFighterTypes = @[@45];
382 NSInteger fighterBonus[] = {0, 0, 2, 5, 9, 14, 14, 22};
383 NSInteger bomberBonus[] = {0, 0, 0, 0, 0, 0, 0, 0};
384 NSInteger attackerBonus[] = {0, 0, 0, 0, 0, 0, 0, 0};
385 NSInteger floatplaneBomberBonus[] = {0, 0, 1, 1, 1, 3, 3, 6};
386 NSInteger floatplaneFighterBonus[] = {0, 0, 0, 0, 0, 0, 0, 0};
387 NSInteger bonus[] = {0, 1, 1, 2, 2, 2, 2, 3};
389 NSInteger extraSeiku = 0;
390 for(NSInteger i = 0; i < 5; i++) {
391 NSString *key = [NSString stringWithFormat:@"onslot_%ld", i];
392 NSNumber *itemCountValue = [self valueForKey:key];
393 NSInteger itemCount = [itemCountValue integerValue];
394 if(itemCount == 0) continue;
396 HMKCSlotItemObject *slotItem = [self slotItemAtIndex:i];
397 NSInteger airLevel = slotItem.alv.integerValue;
399 NSInteger *typeBonus = NULL;
401 HMKCMasterSlotItemObject *master = slotItem.master_slotItem;
402 NSNumber *type2 = master.type_2;
403 if([fighterTypes containsObject:type2]) {
404 typeBonus = fighterBonus;
406 if([bomberTypes containsObject:type2]) {
407 typeBonus = bomberBonus;
409 if([attackerTypes containsObject:type2]) {
410 typeBonus = attackerBonus;
412 if([floatplaneBomberTypes containsObject:type2]) {
413 typeBonus = floatplaneBomberBonus;
415 if([floatplaneFighterTypes containsObject:type2]) {
416 typeBonus = floatplaneFighterBonus;
418 if(!typeBonus) continue;
420 extraSeiku += typeBonus[airLevel] + bonus[airLevel];
423 return @(extraSeiku);
426 + (NSSet *)keyPathsForValuesAffectingTotalDrums
428 return [NSSet setWithObjects:
429 @"slot_0", @"slot_1", @"slot_2", @"slot_3", @"slot_4",
433 - (NSNumber *)totalDrums
435 NSInteger totalBuckets = 0;
436 for(NSInteger i = 0; i < 5; i++) {
437 HMKCSlotItemObject *slotItem = [self slotItemAtIndex:i];
438 NSNumber *masterID = slotItem.slotitem_id;
439 if([masterID isEqualToNumber:@(75)]) {
444 return @(totalBuckets);
447 - (NSNumber *)guardEscaped
449 HMTemporaryDataStore *store = [HMTemporaryDataStore defaultManager];
450 NSError *error = nil;
451 NSArray *array = [store objectsWithEntityName:@"GuardEscaped"
453 predicateFormat:@"shipID = %@ AND ensured = TRUE", self.id];
455 NSLog(@"GuardEscaped is invalid. error -> %@", error);
458 if(!array) return @NO;
460 return array.count == 0 ? @NO : @YES;
463 + (NSSet *)keyPathsForValuesAffectingSteelRequiredInRepair
465 return [NSSet setWithObject:@"nowhp"];
467 - (NSNumber *)steelRequiredInRepair
469 NSInteger steel = self.master_ship.fuel_max.integerValue * 0.06 * (self.maxhp.integerValue - self.nowhp.integerValue);
473 + (NSSet *)keyPathsForValuesAffectingFuelRequiredInRepair
475 return [NSSet setWithObject:@"nowhp"];
477 - (NSNumber *)fuelRequiredInRepair
479 NSInteger fuel = self.master_ship.fuel_max.integerValue * 0.032 * (self.maxhp.integerValue - self.nowhp.integerValue);