Line data Source code
1 0 : /* 2 : 3 : OOCommodities.m 4 : 5 : Oolite 6 : Copyright (C) 2004-2014 Giles C Williams and contributors 7 : 8 : This program is free software; you can redistribute it and/or 9 : modify it under the terms of the GNU General Public License 10 : as published by the Free Software Foundation; either version 2 11 : of the License, or (at your option) any later version. 12 : 13 : This program is distributed in the hope that it will be useful, 14 : but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : GNU General Public License for more details. 17 : 18 : You should have received a copy of the GNU General Public License 19 : along with this program; if not, write to the Free Software 20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 21 : MA 02110-1301, USA. 22 : 23 : */ 24 : 25 : #import "OOCommodities.h" 26 : #import "OOCommodityMarket.h" 27 : 28 : #import "StationEntity.h" 29 : #import "ResourceManager.h" 30 : #import "legacy_random.h" 31 : #import "OOCollectionExtractors.h" 32 : #import "OOJSScript.h" 33 : #import "PlayerEntity.h" 34 : #import "OOStringExpander.h" 35 : 36 : @interface OOCommodities (OOPrivate) 37 : 38 0 : - (NSDictionary *) modifyGood:(NSDictionary *)good withScript:(OOScript *)script atStation:(StationEntity *)station inSystem:(OOSystemID)system localMode:(BOOL)local; 39 0 : - (NSDictionary *) createDefinitionFrom:(NSDictionary *) good price:(OOCreditsQuantity)p andQuantity:(OOCargoQuantity)q forKey:(OOCommodityType)key atStation:(StationEntity *)station inSystem:(OOSystemID)system; 40 : 41 : 42 0 : - (OOCargoQuantity) generateQuantityForGood:(NSDictionary *)good inEconomy:(OOEconomyID)economy; 43 0 : - (OOCreditsQuantity) generatePriceForGood:(NSDictionary *)good inEconomy:(OOEconomyID)economy; 44 : 45 0 : - (float) economicBiasForGood:(NSDictionary *)good inEconomy:(OOEconomyID)economy; 46 0 : - (NSDictionary *) firstModifierForGood:(OOCommodityType)good inClasses:(NSArray *)classes fromList:(NSArray *)definitions; 47 0 : - (OOCreditsQuantity) adjustPrice:(OOCreditsQuantity)price byRule:(NSDictionary *)rule; 48 0 : - (OOCargoQuantity) adjustQuantity:(OOCargoQuantity)quantity byRule:(NSDictionary *)rule; 49 0 : - (NSDictionary *) updateInfoFor:(NSDictionary *)good byRule:(NSDictionary *)rule maxCapacity:(OOCargoQuantity)maxCapacity; 50 : 51 : @end 52 : 53 : 54 : @implementation OOCommodities 55 : 56 : /* Older save games store some commodity information by its old index. */ 57 : + (OOCommodityType) legacyCommodityType:(NSUInteger)i 58 : { 59 : switch (i) 60 : { 61 : case 0: 62 : return @"food"; 63 : case 1: 64 : return @"textiles"; 65 : case 2: 66 : return @"radioactives"; 67 : case 3: 68 : return @"slaves"; 69 : case 4: 70 : return @"liquor_wines"; 71 : case 5: 72 : return @"luxuries"; 73 : case 6: 74 : return @"narcotics"; 75 : case 7: 76 : return @"computers"; 77 : case 8: 78 : return @"machinery"; 79 : case 9: 80 : return @"alloys"; 81 : case 10: 82 : return @"firearms"; 83 : case 11: 84 : return @"furs"; 85 : case 12: 86 : return @"minerals"; 87 : case 13: 88 : return @"gold"; 89 : case 14: 90 : return @"platinum"; 91 : case 15: 92 : return @"gem_stones"; 93 : case 16: 94 : return @"alien_items"; 95 : } 96 : // shouldn't happen 97 : return @"food"; 98 : } 99 : 100 : 101 : 102 0 : - (id) init 103 : { 104 : self = [super init]; 105 : if (self == nil) return nil; 106 : 107 : NSDictionary *rawCommodityLists = [ResourceManager dictionaryFromFilesNamed:@"trade-goods.plist" inFolder:@"Config" mergeMode:MERGE_SMART cache:YES]; 108 : /* // TODO: validation of inputs 109 : // TODO: convert 't', 'kg', 'g' in quantity_unit to 0, 1, 2 110 : // for now it needs them entering as the ints 111 : NSMutableDictionary *validatedCommodityLists = [NSMutableDictionary dictionaryWithCapacity:[rawCommodityLists count]]; 112 : NSString *commodityName = nil; 113 : foreachkey (commodityName, rawCommodityLists) 114 : { 115 : // validate 116 : } 117 : 118 : // _commodityLists = [[NSDictionary dictionaryWithDictionary:validatedCommodityLists] retain]; 119 : */ 120 : 121 : _commodityLists = [[NSDictionary dictionaryWithDictionary:rawCommodityLists] retain]; 122 : 123 : return self; 124 : } 125 : 126 : 127 0 : - (void) dealloc 128 : { 129 : DESTROY(_commodityLists); 130 : 131 : 132 : [super dealloc]; 133 : } 134 : 135 : 136 : - (OOCommodityMarket *) generateManifestForPlayer 137 : { 138 : OOCommodityMarket *market = [[OOCommodityMarket alloc] init]; 139 : 140 : NSString *commodity = nil; 141 : NSMutableDictionary *good = nil; 142 : foreachkey (commodity, _commodityLists) 143 : { 144 : good = [NSMutableDictionary dictionaryWithDictionary:[_commodityLists oo_dictionaryForKey:commodity]]; 145 : [good oo_setUnsignedInteger:0 forKey:kOOCommodityPriceCurrent]; 146 : [good oo_setUnsignedInteger:0 forKey:kOOCommodityQuantityCurrent]; 147 : /* The actual capacity of the player ship is a total, not 148 : * per-good, so is managed separately through PlayerEntity */ 149 : [good oo_setUnsignedInteger:UINT32_MAX forKey:kOOCommodityCapacity]; 150 : [good setObject:commodity forKey:kOOCommodityKey]; 151 : 152 : [market setGood:commodity withInfo:good]; 153 : } 154 : return [market autorelease]; 155 : } 156 : 157 : 158 : - (OOCommodityMarket *) generateBlankMarket 159 : { 160 : OOCommodityMarket *market = [[OOCommodityMarket alloc] init]; 161 : 162 : NSString *commodity = nil; 163 : NSMutableDictionary *good = nil; 164 : foreachkey (commodity, _commodityLists) 165 : { 166 : good = [NSMutableDictionary dictionaryWithDictionary:[_commodityLists oo_dictionaryForKey:commodity]]; 167 : [good oo_setUnsignedInteger:0 forKey:kOOCommodityPriceCurrent]; 168 : [good oo_setUnsignedInteger:0 forKey:kOOCommodityQuantityCurrent]; 169 : [good oo_setUnsignedInteger:0 forKey:kOOCommodityCapacity]; 170 : [good setObject:commodity forKey:kOOCommodityKey]; 171 : 172 : [market setGood:commodity withInfo:good]; 173 : } 174 : return [market autorelease]; 175 : } 176 : 177 : 178 0 : - (NSDictionary *) createDefinitionFrom:(NSDictionary *) good price:(OOCreditsQuantity)p andQuantity:(OOCargoQuantity)q forKey:(OOCommodityType)key atStation:(StationEntity *)station inSystem:(OOSystemID)system 179 : { 180 : NSMutableDictionary *definition = [NSMutableDictionary dictionaryWithDictionary:good]; 181 : [definition oo_setUnsignedInteger:p forKey:kOOCommodityPriceCurrent]; 182 : [definition oo_setUnsignedInteger:q forKey:kOOCommodityQuantityCurrent]; 183 : if (station == nil && [definition objectForKey:kOOCommodityCapacity] == nil) 184 : { 185 : [definition oo_setInteger:MAIN_SYSTEM_MARKET_LIMIT forKey:kOOCommodityCapacity]; 186 : } 187 : 188 : [definition setObject:key forKey:kOOCommodityKey]; 189 : if (station != nil && ![station marketMonitored]) 190 : { 191 : // clear legal status indicators if the market is not monitored 192 : [definition oo_setUnsignedInteger:0 forKey:kOOCommodityLegalityExport]; 193 : [definition oo_setUnsignedInteger:0 forKey:kOOCommodityLegalityImport]; 194 : } 195 : 196 : NSString *goodScriptName = [definition oo_stringForKey:kOOCommodityScript]; 197 : if (goodScriptName == nil) 198 : { 199 : return definition; 200 : } 201 : OOScript *goodScript = [PLAYER commodityScriptNamed:goodScriptName]; 202 : if (goodScript == nil) 203 : { 204 : return definition; 205 : } 206 : return [self modifyGood:definition withScript:goodScript atStation:station inSystem:system localMode:NO]; 207 : } 208 : 209 : 210 0 : - (NSDictionary *) modifyGood:(NSDictionary *)good withScript:(OOScript *)script atStation:(StationEntity *)station inSystem:(OOSystemID)system localMode:(BOOL)localMode 211 : { 212 : NSDictionary *result = nil; 213 : JSContext *context = OOJSAcquireContext(); 214 : jsval rval; 215 : jsval args[] = { 216 : OOJSValueFromNativeObject(context, good), 217 : OOJSValueFromNativeObject(context, station), 218 : INT_TO_JSVAL(system) 219 : }; 220 : BOOL OK = YES; 221 : NSString *errorType = nil; 222 : 223 : if (localMode) 224 : { 225 : errorType = @"local"; 226 : OK = [script callMethod:OOJSID("updateLocalCommodityDefinition") 227 : inContext:context 228 : withArguments:args 229 : count:3 230 : result:&rval]; 231 : } 232 : else 233 : { 234 : errorType = @"general"; 235 : OK = [script callMethod:OOJSID("updateGeneralCommodityDefinition") 236 : inContext:context 237 : withArguments:args 238 : count:3 239 : result:&rval]; 240 : } 241 : 242 : if (!OK) 243 : { 244 : OOLog(@"script.commodityScript.error",@"Could not update %@ commodity definition for %@ - unable to call updateLocalCommodityDefinition",errorType,[good oo_stringForKey:kOOCommodityName]); 245 : OOJSRelinquishContext(context); 246 : return good; 247 : } 248 : 249 : if (!JSVAL_IS_OBJECT(rval)) 250 : { 251 : OOLog(@"script.commodityScript.error",@"Could not update %@ commodity definition for %@ - return value invalid",errorType,[good oo_stringForKey:kOOCommodityKey]); 252 : OOJSRelinquishContext(context); 253 : return good; 254 : } 255 : 256 : result = OOJSNativeObjectFromJSObject(context, JSVAL_TO_OBJECT(rval)); 257 : OOJSRelinquishContext(context); 258 : if (![result isKindOfClass:[NSDictionary class]]) 259 : { 260 : OOLog(@"script.commodityScript.error",@"Could not update %@ commodity definition for %@ - return value invalid",errorType,[good oo_stringForKey:kOOCommodityKey]); 261 : return good; 262 : } 263 : 264 : return result; 265 : } 266 : 267 : 268 : - (OOCommodityMarket *) generateMarketForSystemWithEconomy:(OOEconomyID)economy andScript:(NSString *)scriptName 269 : { 270 : OOScript *script = [PLAYER commodityScriptNamed:scriptName]; 271 : 272 : OOCommodityMarket *market = [[OOCommodityMarket alloc] init]; 273 : 274 : NSString *commodity = nil; 275 : NSDictionary *good = nil; 276 : foreachkey (commodity, _commodityLists) 277 : { 278 : good = [_commodityLists oo_dictionaryForKey:commodity]; 279 : OOCargoQuantity q = [self generateQuantityForGood:good inEconomy:economy]; 280 : // main system market limited to 127 units of each item 281 : OOCargoQuantity cap = [good oo_unsignedIntForKey:kOOCommodityCapacity defaultValue:MAIN_SYSTEM_MARKET_LIMIT]; 282 : if (q > cap) 283 : { 284 : q = cap; 285 : } 286 : OOCreditsQuantity p = [self generatePriceForGood:good inEconomy:economy]; 287 : good = [self createDefinitionFrom:good price:p andQuantity:q forKey:commodity atStation:nil inSystem:[UNIVERSE currentSystemID]]; 288 : 289 : if (script != nil) 290 : { 291 : good = [self modifyGood:good withScript:script atStation:nil inSystem:[UNIVERSE currentSystemID] localMode:YES]; 292 : } 293 : [market setGood:commodity withInfo:good]; 294 : } 295 : return [market autorelease]; 296 : } 297 : 298 : 299 : - (OOCommodityMarket *) generateMarketForStation:(StationEntity *)station 300 : { 301 : NSArray *marketDefinition = [station marketDefinition]; 302 : NSString *marketScriptName = [station marketScriptName]; 303 : OOScript *marketScript = [PLAYER commodityScriptNamed:marketScriptName]; 304 : if (marketDefinition == nil && marketScript == nil) 305 : { 306 : OOCommodityMarket *market = [self generateBlankMarket]; 307 : return market; 308 : } 309 : 310 : OOCommodityMarket *market = [[OOCommodityMarket alloc] init]; 311 : OOCargoQuantity capacity = [station marketCapacity]; 312 : OOCommodityMarket *mainMarket = [UNIVERSE commodityMarket]; 313 : 314 : NSString *commodity = nil; 315 : NSDictionary *good = nil; 316 : foreachkey (commodity, _commodityLists) 317 : { 318 : good = [_commodityLists oo_dictionaryForKey:commodity]; 319 : OOCargoQuantity baseCapacity = [good oo_unsignedIntForKey:kOOCommodityCapacity defaultValue:MAIN_SYSTEM_MARKET_LIMIT]; 320 : 321 : // important - ensure baseCapacity cannot be zero 322 : if (!baseCapacity) baseCapacity = MAIN_SYSTEM_MARKET_LIMIT; 323 : 324 : OOCargoQuantity q = [mainMarket quantityForGood:commodity]; 325 : OOCreditsQuantity p = [mainMarket priceForGood:commodity]; 326 : 327 : if (marketScript == nil) 328 : { 329 : NSDictionary *modifier = [self firstModifierForGood:commodity inClasses:[good oo_arrayForKey:kOOCommodityClasses] fromList:marketDefinition]; 330 : good = [self updateInfoFor:good byRule:modifier maxCapacity:capacity]; 331 : p = [self adjustPrice:p byRule:modifier]; 332 : 333 : // first, scale to this station's capacity for this good 334 : OOCargoQuantity localCapacity = [good oo_unsignedIntForKey:kOOCommodityCapacity]; 335 : if (localCapacity > capacity) 336 : { 337 : localCapacity = capacity; 338 : } 339 : q = (q * localCapacity) / baseCapacity; 340 : q = [self adjustQuantity:q byRule:modifier]; 341 : if (q > localCapacity) 342 : { 343 : q = localCapacity; // cap 344 : } 345 : } 346 : else 347 : { 348 : // only scale to market at this stage 349 : q = (q * capacity) / baseCapacity; 350 : } 351 : 352 : good = [self createDefinitionFrom:good price:p andQuantity:q forKey:commodity atStation:station inSystem:[UNIVERSE currentSystemID]]; 353 : if (marketScript != nil) 354 : { 355 : good = [self modifyGood:good withScript:marketScript atStation:station inSystem:[UNIVERSE currentSystemID] localMode:YES]; 356 : } 357 : 358 : [market setGood:commodity withInfo:good]; 359 : } 360 : return [market autorelease]; 361 : } 362 : 363 : 364 : - (NSUInteger) count 365 : { 366 : return [_commodityLists count]; 367 : } 368 : 369 : 370 : - (NSArray *) goods 371 : { 372 : return [_commodityLists allKeys]; 373 : } 374 : 375 : 376 : - (BOOL) goodDefined:(NSString *)key 377 : { 378 : return ([_commodityLists oo_dictionaryForKey:key] != nil); 379 : } 380 : 381 : - (NSString *) goodNamed:(NSString *)name 382 : { 383 : NSString *commodity = nil; 384 : foreachkey (commodity, _commodityLists) 385 : { 386 : NSDictionary *good = [_commodityLists oo_dictionaryForKey:commodity]; 387 : if ([OOExpand([good oo_stringForKey:kOOCommodityName]) isEqualToString:name]) { 388 : return commodity; 389 : } 390 : } 391 : return nil; 392 : } 393 : 394 : 395 : 396 : - (NSString *) getRandomCommodity 397 : { 398 : NSArray *keys = [_commodityLists allKeys]; 399 : NSUInteger idx = Ranrot() % [keys count]; 400 : return [keys oo_stringAtIndex:idx]; 401 : } 402 : 403 : 404 : - (OOMassUnit) massUnitForGood:(NSString *)good 405 : { 406 : NSDictionary *definition = [_commodityLists oo_dictionaryForKey:good]; 407 : if (definition == nil) 408 : { 409 : return UNITS_TONS; 410 : } 411 : return [definition oo_unsignedIntForKey:kOOCommodityContainer]; 412 : } 413 : 414 : 415 : 416 : 417 0 : - (OOCargoQuantity) generateQuantityForGood:(NSDictionary *)good inEconomy:(OOEconomyID)economy 418 : { 419 : float bias = [self economicBiasForGood:good inEconomy:economy]; 420 : 421 : float base = [good oo_floatForKey:kOOCommodityQuantityAverage]; 422 : float econ = base * [good oo_floatForKey:kOOCommodityQuantityEconomic] * bias; 423 : float random = base * [good oo_floatForKey:kOOCommodityQuantityRandom] * (randf() - randf()); 424 : base += econ + random; 425 : if (base < 0.0) 426 : { 427 : return 0; 428 : } 429 : else 430 : { 431 : return (OOCargoQuantity)base; 432 : } 433 : } 434 : 435 : 436 0 : - (OOCreditsQuantity) generatePriceForGood:(NSDictionary *)good inEconomy:(OOEconomyID)economy 437 : { 438 : float bias = [self economicBiasForGood:good inEconomy:economy]; 439 : 440 : float base = [good oo_floatForKey:kOOCommodityPriceAverage]; 441 : float econ = base * [good oo_floatForKey:kOOCommodityPriceEconomic] * -bias; 442 : float random = base * [good oo_floatForKey:kOOCommodityPriceRandom] * (randf() - randf()); 443 : base += econ + random; 444 : if (base < 0.0) 445 : { 446 : return 0; 447 : } 448 : else 449 : { 450 : return (OOCreditsQuantity)base; 451 : } 452 : } 453 : 454 : 455 : - (OOCreditsQuantity) samplePriceForCommodity:(OOCommodityType)commodity inEconomy:(OOEconomyID)economy withScript:(NSString *)scriptName inSystem:(OOSystemID)system 456 : { 457 : NSDictionary *good = [_commodityLists oo_dictionaryForKey:commodity]; 458 : if (good == nil) 459 : { 460 : return 0; 461 : } 462 : OOCreditsQuantity p = [self generatePriceForGood:good inEconomy:economy]; 463 : 464 : good = [self createDefinitionFrom:good price:p andQuantity:0 forKey:commodity atStation:nil inSystem:system]; 465 : if (scriptName != nil) 466 : { 467 : OOScript *script = [PLAYER commodityScriptNamed:scriptName]; 468 : if (script != nil) 469 : { 470 : good = [self modifyGood:good withScript:script atStation:nil inSystem:system localMode:YES]; 471 : } 472 : } 473 : return [good oo_unsignedIntegerForKey:kOOCommodityPriceCurrent]; 474 : } 475 : 476 : 477 : // positive = exporter; negative = importer; range -1.0 .. +1.0 478 0 : - (float) economicBiasForGood:(NSDictionary *)good inEconomy:(OOEconomyID)economy 479 : { 480 : OOEconomyID exporter = [good oo_intForKey:kOOCommodityPeakExport]; 481 : OOEconomyID importer = [good oo_intForKey:kOOCommodityPeakImport]; 482 : 483 : // *2 and /2 to work in ints at this stage 484 : int exDiff = abs(economy-exporter)*2; 485 : int imDiff = abs(economy-importer)*2; 486 : int distance = (exDiff+imDiff)/2; 487 : 488 : if (exDiff == imDiff) 489 : { 490 : // neutral economy 491 : return 0.0; 492 : } 493 : else if (exDiff > imDiff) 494 : { 495 : // closer to the importer, so return -ve 496 : return -(1.0-((float)imDiff/(float)distance)); 497 : } 498 : else 499 : { 500 : // closer to the exporter, so return +ve 501 : return 1.0-((float)exDiff/(float)distance); 502 : } 503 : } 504 : 505 : 506 0 : - (NSDictionary *) firstModifierForGood:(OOCommodityType)good inClasses:(NSArray *)classes fromList:(NSArray *)definitions 507 : { 508 : NSUInteger i; 509 : for (i = 0; i < [definitions count]; i++) 510 : { 511 : NSDictionary *definition = [definitions oo_dictionaryAtIndex:i]; 512 : if (definition != nil) 513 : { 514 : NSString *applicationType = [definition oo_stringForKey:kOOCommodityMarketType defaultValue:kOOCommodityMarketTypeValueDefault]; 515 : NSString *applicationName = [definition oo_stringForKey:kOOCommodityMarketName defaultValue:@""]; 516 : 517 : if ( 518 : [applicationType isEqualToString:kOOCommodityMarketTypeValueDefault] 519 : || ([applicationType isEqualToString:kOOCommodityMarketTypeValueGood] && [applicationName isEqualToString:good]) 520 : || ([applicationType isEqualToString:kOOCommodityMarketTypeValueClass] && [classes containsObject:applicationName]) 521 : ) 522 : { 523 : return definition; 524 : } 525 : } 526 : } 527 : // return a blank dictionary - default values will do the rest 528 : return [NSDictionary dictionary]; 529 : } 530 : 531 : 532 0 : - (OOCreditsQuantity) adjustPrice:(OOCreditsQuantity)price byRule:(NSDictionary *)rule 533 : { 534 : float p = (float)price; // work in floats to avoid rounding problems 535 : float pa = [rule oo_floatForKey:kOOCommodityMarketPriceAdder defaultValue:0.0]; 536 : float pm = [rule oo_floatForKey:kOOCommodityMarketPriceMultiplier defaultValue:1.0]; 537 : if (pm <= 0.0 && pa <= 0.0) 538 : { 539 : // setting a price multiplier of 0 forces the price to zero 540 : return 0; 541 : } 542 : float pr = [rule oo_floatForKey:kOOCommodityMarketPriceRandomiser defaultValue:0.0]; 543 : p += pa; 544 : p = (p * pm) + (p * pr * (randf()-randf())); 545 : if (p < 1.0) 546 : { 547 : // random variation and non-zero price multiplier can't reduce 548 : // price below 1 decicredit 549 : p = 1.0; 550 : } 551 : return (OOCreditsQuantity) p; 552 : } 553 : 554 : 555 0 : - (OOCargoQuantity) adjustQuantity:(OOCargoQuantity)quantity byRule:(NSDictionary *)rule 556 : { 557 : float q = (float)quantity; // work in floats to avoid rounding problems 558 : float qa = [rule oo_floatForKey:kOOCommodityMarketQuantityAdder defaultValue:0.0]; 559 : float qm = [rule oo_floatForKey:kOOCommodityMarketQuantityMultiplier defaultValue:1.0]; 560 : if (qm <= 0.0 && qa <= 0.0) 561 : { 562 : // setting a price multiplier of 0 forces the price to zero 563 : return 0; 564 : } 565 : float qr = [rule oo_floatForKey:kOOCommodityMarketQuantityRandomiser defaultValue:0.0]; 566 : q += qa; 567 : q = (q * qm) + (q * qr * (randf()-randf())); 568 : if (q < 0.0) 569 : { 570 : // random variation and non-zero price multiplier can't reduce 571 : // quantity below zero 572 : q = 0.0; 573 : } 574 : // may be over station capacity - that gets capped later 575 : return (OOCargoQuantity) q; 576 : } 577 : 578 : 579 0 : - (NSDictionary *) updateInfoFor:(NSDictionary *)good byRule:(NSDictionary *)rule maxCapacity:(OOCargoQuantity)maxCapacity 580 : { 581 : NSMutableDictionary *tmp = [NSMutableDictionary dictionaryWithDictionary:good]; 582 : NSInteger import = [rule oo_integerForKey:kOOCommodityMarketLegalityImport defaultValue:-1]; 583 : if (import >= 0) 584 : { 585 : [tmp oo_setInteger:import forKey:kOOCommodityLegalityImport]; 586 : } 587 : 588 : NSInteger export = [rule oo_integerForKey:kOOCommodityMarketLegalityExport defaultValue:-1]; 589 : if (export >= 0) 590 : { 591 : [tmp oo_setInteger:import forKey:kOOCommodityLegalityExport]; 592 : } 593 : 594 : NSInteger capacity = [rule oo_integerForKey:kOOCommodityMarketCapacity defaultValue:-1]; 595 : if (capacity >= 0 && capacity <= (NSInteger)maxCapacity) 596 : { 597 : [tmp oo_setInteger:capacity forKey:kOOCommodityCapacity]; 598 : } 599 : else 600 : { 601 : // set to the station max capacity 602 : [tmp oo_setInteger:maxCapacity forKey:kOOCommodityCapacity]; 603 : } 604 : 605 : return [[tmp copy] autorelease]; 606 : } 607 : 608 : 609 : 610 : @end