2 // HMCalculateDamageCommand.m
5 // Created by Hori,Masaki on 2014/05/22.
6 // Copyright (c) 2014年 Hori,Masaki. All rights reserved.
9 #import "HMCalculateDamageCommand.h"
11 #import "HMTemporaryDataStore.h"
12 #import "HMServerDataStore.h"
15 #define DAMAGE_CHECK 0
17 typedef NS_ENUM(NSUInteger, HMBattleType) {
23 @interface HMCalculateDamageCommand ()
24 @property (nonatomic, strong) HMTemporaryDataStore *store;
25 @property HMBattleType battleType;
28 @implementation HMCalculateDamageCommand
34 _store = [HMTemporaryDataStore oneTimeEditor];
41 NSManagedObjectContext *moc = self.store.managedObjectContext;
44 NSArray *array = [self.store objectsWithEntityName:@"Battle"
48 [self log:@"%s error: %@", __PRETTY_FUNCTION__, error];
51 for(id object in array) {
52 [moc deleteObject:object];
55 [self.store saveAction:nil];
60 NSManagedObjectContext *moc = self.store.managedObjectContext;
63 NSArray *array = [self.store objectsWithEntityName:@"Damage"
67 [self log:@"%s error: %@", __PRETTY_FUNCTION__, error];
70 for(id object in array) {
71 [moc deleteObject:object];
74 [self.store saveAction:nil];
79 NSManagedObjectContext *moc = self.store.managedObjectContext;
82 id battle = [NSEntityDescription insertNewObjectForEntityForName:@"Battle"
83 inManagedObjectContext:moc];
85 [battle setValue:@([[self.arguments valueForKey:@"api_deck_id"] integerValue]) forKeyPath:@"deckId"];
86 [battle setValue:@([[self.arguments valueForKey:@"api_maparea_id"] integerValue]) forKeyPath:@"mapArea"];
87 [battle setValue:@([[self.arguments valueForKey:@"api_mapinfo_no"] integerValue]) forKeyPath:@"mapInfo"];
88 [battle setValue:@([[self.json valueForKeyPath:@"api_data.api_no"] integerValue]) forKeyPath:@"no"];
90 [self.store saveAction:nil];
93 - (void)updateBattleCell
96 NSArray *battles = [self.store objectsWithEntityName:@"Battle"
100 [self log:@"%s error: %@", __PRETTY_FUNCTION__, error];
102 if(battles.count == 0) {
103 NSLog(@"Battle is invalid.");
106 id battle = battles[0];
108 id battleCell = [battle valueForKey:@"no"];
109 if([battleCell integerValue] == 0) {
112 if([self.api hasSuffix:@"next"]) {
115 [battle setValue:battleCell forKeyPath:@"battleCell"];
120 NSError *error = nil;
121 NSArray *battles = [self.store objectsWithEntityName:@"Battle"
125 [self log:@"%s error: %@", __PRETTY_FUNCTION__, error];
127 if(battles.count == 0) {
128 NSLog(@"Battle is invalid.");
131 id battle = battles[0];
133 [battle setValue:@([[self.json valueForKeyPath:@"api_data.api_no"] integerValue]) forKeyPath:@"no"];
135 [self.store saveAction:nil];
138 - (NSMutableArray *)damages
140 NSManagedObjectContext *moc = self.store.managedObjectContext;
142 NSError *error = nil;
143 NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"id" ascending:YES];
144 NSArray *array = [self.store objectsWithEntityName:@"Damage"
145 sortDescriptors:@[sortDescriptor]
149 [self log:@"%s error: %@", __PRETTY_FUNCTION__, error];
151 // TODO: error handling
153 NSInteger frendShipCount = 12;
154 if(array.count != frendShipCount) {
157 NSArray *battles = [self.store objectsWithEntityName:@"Battle"
161 [self log:@"%s error: %@", __PRETTY_FUNCTION__, error];
163 if(battles.count == 0) {
164 NSLog(@"Battle is invalid.");
165 return [NSMutableArray new];
167 id battle = battles[0];
170 NSMutableArray *damages = [NSMutableArray new];
171 for(NSInteger i = 0; i < frendShipCount; i++) {
172 id damage = [NSEntityDescription insertNewObjectForEntityForName:@"Damage"
173 inManagedObjectContext:moc];
174 [damage setValue:battle forKeyPath:@"battle"];
175 [damage setValue:@(i) forKeyPath:@"id"];
176 [damages addObject:damage];
181 return [NSMutableArray arrayWithArray:array];
184 - (void)calculateHougeki:(NSMutableArray *)damages targetsKeyPath:(NSString *)targetKeyPath damageKeyPath:(NSString *)damageKeyPath
187 NSLog(@"Start Hougeki %@", targetKeyPath);
189 id targetShips = [self.json valueForKeyPath:targetKeyPath];
190 if(!targetShips || [targetShips isKindOfClass:[NSNull class]]) return;
192 id hougeki1Damages = [self.json valueForKeyPath:damageKeyPath];
194 NSInteger offset = self.calcSecondFleet ? 6 : 0;
195 for(NSArray *array in targetShips) {
196 if(![array isKindOfClass:[NSArray class]]) {
202 for(id ship in array) {
203 NSInteger target = [ship integerValue];
205 NSLog(@"Hougeki target -> %ld", target + offset);
207 if(target < 0 || target > 6) {
212 id damageObject = [damages objectAtIndex:target - 1 + offset];
213 NSInteger damage = [[[hougeki1Damages objectAtIndex:i] objectAtIndex:j] integerValue];
214 damage += [[damageObject valueForKey:@"damage"] integerValue];
215 [damageObject setValue:@(damage) forKeyPath:@"damage"];
218 NSLog(@"Hougeki %ld -> %ld", target + offset, damage);
227 - (void)calculateFDam:(NSMutableArray *)damages fdamKeyPath:(NSString *)fdamKeyPath
230 NSLog(@"Start FDam %@", fdamKeyPath);
232 id koukuDamage = [self.json valueForKeyPath:fdamKeyPath];
233 if(!koukuDamage || [koukuDamage isEqual:[NSNull null]]) return;
235 NSInteger offset = self.calcSecondFleet ? 6 : 0;
236 for(NSInteger i = 1; i <= 6; i++) {
237 id damageObject = [damages objectAtIndex:i - 1 + offset];
238 NSInteger damage = [[koukuDamage objectAtIndex:i] integerValue];
239 damage += [[damageObject valueForKey:@"damage"] integerValue];
240 [damageObject setValue:@(damage) forKeyPath:@"damage"];
243 NSLog(@"FDam %ld -> %ld", i + offset, damage);
248 - (BOOL)isCombinedBattle
250 return [self.api hasPrefix:@"/kcsapi/api_req_combined_battle"];
253 - (void)calculateBattle
255 [self updateBattleCell];
260 NSMutableArray *damages = [self damages];
263 [self calculateFDam:damages
264 fdamKeyPath:@"api_data.api_kouku.api_stage3.api_fdam"];
266 if(self.isCombinedBattle) {
267 [self calculateFDam:damages
268 fdamKeyPath:@"api_data.api_kouku2.api_stage3.api_fdam"];
270 self.calcSecondFleet = YES;
271 [self calculateFDam:damages
272 fdamKeyPath:@"api_data.api_kouku.api_stage3_combined.api_fdam"];
273 [self calculateFDam:damages
274 fdamKeyPath:@"api_data.api_kouku2.api_stage3_combined.api_fdam"];
275 self.calcSecondFleet = NO;
277 [self calculateFDam:damages
278 fdamKeyPath:@"api_data.api_kouku2.api_stage3.api_fdam"];
282 self.calcSecondFleet = self.isCombinedBattle;
283 [self calculateFDam:damages
284 fdamKeyPath:@"api_data.api_opening_atack.api_fdam"];
285 self.calcSecondFleet = NO;
288 self.calcSecondFleet = self.isCombinedBattle && self.battleType == typeCombinedAir;
289 [self calculateHougeki:damages
290 targetsKeyPath:@"api_data.api_hougeki1.api_df_list"
291 damageKeyPath:@"api_data.api_hougeki1.api_damage"];
292 self.calcSecondFleet = NO;
295 [self calculateHougeki:damages
296 targetsKeyPath:@"api_data.api_hougeki2.api_df_list"
297 damageKeyPath:@"api_data.api_hougeki2.api_damage"];
300 self.calcSecondFleet = self.isCombinedBattle && self.battleType == typeCombinedWater;
301 [self calculateHougeki:damages
302 targetsKeyPath:@"api_data.api_hougeki3.api_df_list"
303 damageKeyPath:@"api_data.api_hougeki3.api_damage"];
304 self.calcSecondFleet = NO;
307 self.calcSecondFleet = self.isCombinedBattle;
308 [self calculateFDam:damages
309 fdamKeyPath:@"api_data.api_raigeki.api_fdam"];
310 self.calcSecondFleet = NO;
312 [self.store saveAction:nil];
315 - (void)calculateMidnightBattle
317 [self updateBattleCell];
320 NSMutableArray *damages = [self damages];
323 self.calcSecondFleet = self.isCombinedBattle;
324 [self calculateHougeki:damages
325 targetsKeyPath:@"api_data.api_hougeki.api_df_list"
326 damageKeyPath:@"api_data.api_hougeki.api_damage"];
327 self.calcSecondFleet = NO;
329 [self.store saveAction:nil];
332 - (NSArray *)deckWithNumber:(NSNumber *)number
334 return [NSArray array];
339 NSArray *damages = nil;
341 NSError *error = nil;
342 NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"id" ascending:YES];
343 damages = [self.store objectsWithEntityName:@"Damage"
344 sortDescriptors:@[sortDescriptor]
348 [self log:@"%s error: %@", __PRETTY_FUNCTION__, error];
352 if(damages.count != 12) {
353 [self log:@"Damage is invalid. count %lx", damages.count];
358 NSArray *array = [self.store objectsWithEntityName:@"Battle"
362 [self log:@"%s error: %@", __PRETTY_FUNCTION__, error];
365 if(array.count == 0) {
366 [self log:@"Battle is invalid. %s", __PRETTY_FUNCTION__];
370 HMServerDataStore *serverStore = [HMServerDataStore oneTimeEditor];
371 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id = %@", [array[0] valueForKey:@"deckId"]];
373 for(NSInteger i = 0; i < 2; i++) {
376 NSArray *decks = [serverStore objectsWithEntityName:@"Deck"
380 [self log:@"%s error: %@", __PRETTY_FUNCTION__, error];
384 if(decks.count == 0) {
385 [self log:@"Deck is invalid. %s", __PRETTY_FUNCTION__];
389 NSMutableArray *shipIds = [NSMutableArray new];
390 [shipIds addObject:[deck valueForKey:@"ship_0"]];
391 [shipIds addObject:[deck valueForKey:@"ship_1"]];
392 [shipIds addObject:[deck valueForKey:@"ship_2"]];
393 [shipIds addObject:[deck valueForKey:@"ship_3"]];
394 [shipIds addObject:[deck valueForKey:@"ship_4"]];
395 [shipIds addObject:[deck valueForKey:@"ship_5"]];
397 NSMutableArray *ships = [NSMutableArray new];
398 for(id shipId in shipIds) {
400 NSArray *ship = [serverStore objectsWithEntityName:@"Ship"
402 predicateFormat:@"id = %@", @([shipId integerValue])];
404 [self log:@"%s error: %@", __PRETTY_FUNCTION__, error];
406 if(ship.count != 0 && ![ship[0] isEqual:[NSNull null]]) {
407 [ships addObject:ship[0]];
411 NSUInteger shipCount = ships.count;
412 NSUInteger offset = (self.isCombinedBattle && !firstRun) ? 6 : 0;
413 for(NSInteger i = 0; i < shipCount; i++) {
415 NSInteger damage = [[damages[i + offset] valueForKey:@"damage"] integerValue];
416 NSInteger nowhp = [[ship valueForKey:@"nowhp"] integerValue];
418 [ship setValue:@(nowhp) forKeyPath:@"nowhp"];
421 predicate = [NSPredicate predicateWithFormat:@"id = %@", @2];
424 if(!self.isCombinedBattle) break;
427 [serverStore saveAction:nil];
432 if([self.api isEqualToString:@"/kcsapi/api_req_map/start"]) {
437 if([self.api isEqualToString:@"/kcsapi/api_req_map/next"]) {
439 [self updateBattleCell];
443 if([self.api isEqualToString:@"/kcsapi/api_req_sortie/battle"]) {
444 [self calculateBattle];
447 if([self.api isEqualToString:@"/kcsapi/api_req_sortie/airbattle"]) {
448 [self calculateBattle];
451 if([self.api isEqualToString:@"/kcsapi/api_req_battle_midnight/battle"]
452 || [self.api isEqualToString:@"/kcsapi/api_req_battle_midnight/sp_midnight"]) {
453 [self calculateMidnightBattle];
458 /kcsapi/api_req_combined_battle/battle_water
459 /kcsapi/api_req_combined_battle/midnight_battle
460 /kcsapi/api_req_combined_battle/battleresult
463 if([self.api isEqualToString:@"/kcsapi/api_req_combined_battle/battle"]
464 || [self.api isEqualToString:@"/kcsapi/api_req_combined_battle/airbattle"]) {
465 self.battleType = typeCombinedAir;
466 [self calculateBattle];
469 if([self.api isEqualToString:@"/kcsapi/api_req_combined_battle/battle_water"]) {
470 self.battleType = typeCombinedWater;
471 [self calculateBattle];
475 if([self.api isEqualToString:@"/kcsapi/api_req_combined_battle/midnight_battle"]
476 || [self.api isEqualToString:@"/kcsapi/api_req_combined_battle/sp_midnight"]) {
477 [self calculateMidnightBattle];
481 if([self.api isEqualToString:@"/kcsapi/api_req_sortie/battleresult"]
482 || [self.api isEqualToString:@"/kcsapi/api_req_combined_battle/battleresult"]) {
488 NSLog(@"undefined battle type");