Line data Source code
1 0 : /*
2 :
3 : PlayerEntityScriptMethods.m
4 :
5 : Oolite
6 : Copyright (C) 2004-2013 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 "PlayerEntityScriptMethods.h"
26 : #import "PlayerEntityLoadSave.h"
27 :
28 : #import "Universe.h"
29 : #import "OOCollectionExtractors.h"
30 : #import "OOConstToString.h"
31 : #import "OOStringParsing.h"
32 :
33 : #import "OOStringExpander.h"
34 : #import "OOSystemDescriptionManager.h"
35 :
36 : #import "StationEntity.h"
37 :
38 : @implementation PlayerEntity (ScriptMethods)
39 :
40 : - (unsigned) score
41 : {
42 : return ship_kills;
43 : }
44 :
45 :
46 : - (void) setScore:(unsigned)value
47 : {
48 : ship_kills = value;
49 : }
50 :
51 :
52 : - (double) creditBalance
53 : {
54 : return 0.1 * credits;
55 : }
56 :
57 :
58 : - (void) setCreditBalance:(double)value
59 : {
60 : credits = OODeciCreditsFromDouble(value * 10.0);
61 : }
62 :
63 :
64 : - (NSString *) dockedStationName
65 : {
66 : return [[self dockedStation] name];
67 : }
68 :
69 :
70 : - (NSString *) dockedStationDisplayName
71 : {
72 : return [[self dockedStation] displayName];
73 : }
74 :
75 :
76 : - (BOOL) dockedAtMainStation
77 : {
78 : return [self status] == STATUS_DOCKED && [self dockedStation] == [UNIVERSE station];
79 : }
80 :
81 :
82 : - (void) awardCommodityType:(OOCommodityType)type amount:(OOCargoQuantity)amount
83 : {
84 : OOMassUnit unit;
85 :
86 : if (![[UNIVERSE commodities] goodDefined:type])
87 : {
88 : return;
89 : }
90 :
91 : OOLog(@"script.debug.note.awardCargo", @"Going to award cargo: %d x '%@'", amount, type);
92 :
93 : unit = [shipCommodityData massUnitForGood:type];
94 :
95 : if ([self status] != STATUS_DOCKED)
96 : {
97 : // in-flight
98 : while (amount)
99 : {
100 : if (unit != UNITS_TONS)
101 : {
102 : if (specialCargo)
103 : {
104 : // is this correct behaviour?
105 : [shipCommodityData addQuantity:amount forGood:type];
106 : }
107 : else
108 : {
109 : int amount_per_container = (unit == UNITS_KILOGRAMS)? 1000 : 1000000;
110 : while (amount > 0)
111 : {
112 : int smaller_quantity = 1 + ((amount - 1) % amount_per_container);
113 : if ([cargo count] < [self maxAvailableCargoSpace])
114 : {
115 : ShipEntity* container = [UNIVERSE newShipWithRole:@"1t-cargopod"];
116 : if (container)
117 : {
118 : // the cargopod ship is just being set up. If ejected, will call UNIVERSE addEntity
119 : // [container wasAddedToUniverse]; // seems to be not needed anymore for pods
120 : [container setScanClass: CLASS_CARGO];
121 : [container setStatus:STATUS_IN_HOLD];
122 : [container setCommodity:type andAmount:smaller_quantity];
123 : [cargo addObject:container];
124 : [container release];
125 : }
126 : }
127 : amount -= smaller_quantity;
128 : }
129 : }
130 : }
131 : else if (!specialCargo)
132 : // no adding TCs while special cargo in hold
133 : {
134 : // put each ton in a separate container
135 : while (amount)
136 : {
137 : if ([cargo count] < [self maxAvailableCargoSpace])
138 : {
139 : ShipEntity* container = [UNIVERSE newShipWithRole:@"1t-cargopod"];
140 : if (container)
141 : {
142 : // the cargopod ship is just being set up. If ejected, will call UNIVERSE addEntity
143 : // [container wasAddedToUniverse]; // seems to be not needed anymore for pods
144 : [container setScanClass: CLASS_CARGO];
145 : [container setStatus:STATUS_IN_HOLD];
146 : [container setCommodity:type andAmount:1];
147 : [cargo addObject:container];
148 : [container release];
149 : }
150 : }
151 : amount--;
152 : }
153 : }
154 : }
155 : }
156 : else
157 : { // docked
158 : // like purchasing a commodity
159 : int manifest_quantity = [shipCommodityData quantityForGood:type];
160 : while ((amount)&&(current_cargo < [self maxAvailableCargoSpace]))
161 : {
162 : manifest_quantity++;
163 : amount--;
164 : if (unit == UNITS_TONS) current_cargo++;
165 : }
166 : [shipCommodityData setQuantity:manifest_quantity forGood:type];
167 : }
168 : [self calculateCurrentCargo];
169 : }
170 :
171 :
172 : - (void) resetScannerZoom
173 : {
174 : scanner_zoom_rate = SCANNER_ZOOM_RATE_DOWN;
175 : }
176 :
177 :
178 : - (OOGalaxyID) currentGalaxyID
179 : {
180 : return galaxy_number;
181 : }
182 :
183 :
184 : - (OOSystemID) currentSystemID
185 : {
186 : if ([UNIVERSE sun] == nil) return -1; // Interstellar space
187 : return [UNIVERSE currentSystemID];
188 : }
189 :
190 :
191 : - (void) setMissionChoice:(NSString *)newChoice
192 : {
193 : [self setMissionChoice:newChoice keyPress:@"" withEvent:YES];
194 : }
195 :
196 :
197 : - (void) setMissionChoice:(NSString *)newChoice withEvent:(BOOL)withEvent
198 : {
199 : [self setMissionChoice:newChoice keyPress:@"" withEvent:withEvent];
200 : }
201 :
202 :
203 : - (void) setMissionChoice:(NSString *)newChoice keyPress:(NSString *)keyPress
204 : {
205 : [self setMissionChoice:newChoice keyPress:keyPress withEvent:YES];
206 : }
207 :
208 :
209 : - (void) setMissionChoice:(NSString *)newChoice keyPress:(NSString *)keyPress withEvent:(BOOL)withEvent
210 : {
211 : BOOL equal = [newChoice isEqualToString:missionChoice] || (newChoice == missionChoice); // Catch both being nil as well
212 : if (!equal)
213 : {
214 : if (newChoice == nil)
215 : {
216 : NSString *oldChoice = missionChoice;
217 : [missionChoice autorelease];
218 : missionChoice = nil;
219 : if (withEvent) [self doScriptEvent:OOJSID("missionChoiceWasReset") withArgument:oldChoice];
220 : }
221 : else
222 : {
223 : [missionChoice autorelease];
224 : missionChoice = [newChoice copy];
225 : }
226 : }
227 : equal = [keyPress isEqualToString:missionKeyPress] || (keyPress == missionKeyPress);
228 : if (!equal)
229 : {
230 : [missionKeyPress autorelease];
231 : missionKeyPress = [keyPress copy];
232 : }
233 : }
234 :
235 :
236 : - (void) allowMissionInterrupt
237 : {
238 : _missionAllowInterrupt = YES;
239 : }
240 :
241 :
242 : - (OOTimeDelta) scriptTimer
243 : {
244 : return script_time;
245 : }
246 :
247 :
248 : /* FIXME: these next three functions seed the RNG when called. That
249 : * could cause unwanted effects - should save its state, and then
250 : * reset it after generating the number. */
251 : - (unsigned) systemPseudoRandom100
252 : {
253 : seed_RNG_only_for_planet_description([[UNIVERSE systemManager] getRandomSeedForCurrentSystem]);
254 : return (gen_rnd_number() * 256 + gen_rnd_number()) % 100;
255 : }
256 :
257 :
258 : - (unsigned) systemPseudoRandom256
259 : {
260 : seed_RNG_only_for_planet_description([[UNIVERSE systemManager] getRandomSeedForCurrentSystem]);
261 : return gen_rnd_number();
262 : }
263 :
264 :
265 : - (double) systemPseudoRandomFloat
266 : {
267 : seed_RNG_only_for_planet_description([[UNIVERSE systemManager] getRandomSeedForCurrentSystem]);
268 : unsigned a = gen_rnd_number();
269 : unsigned b = gen_rnd_number();
270 : unsigned c = gen_rnd_number();
271 :
272 : a = (a << 16) | (b << 8) | c;
273 : return (double)a / (double)0x01000000;
274 :
275 : }
276 :
277 :
278 : - (NSDictionary *) passengerContractMarker:(OOSystemID)system
279 : {
280 : return [[[NSDictionary dictionaryWithObjectsAndKeys:
281 : [NSNumber numberWithInt:system], @"system",
282 : MISSION_DEST_LEGACY, @"name",
283 : @"orangeColor", @"markerColor",
284 : @"MARKER_DIAMOND", @"markerShape",
285 : nil] retain] autorelease];
286 : }
287 :
288 :
289 : - (NSDictionary *) parcelContractMarker:(OOSystemID)system
290 : {
291 : return [[[NSDictionary dictionaryWithObjectsAndKeys:
292 : [NSNumber numberWithInt:system], @"system",
293 : MISSION_DEST_LEGACY, @"name",
294 : @"orangeColor", @"markerColor",
295 : @"MARKER_PLUS", @"markerShape",
296 : nil] retain] autorelease];
297 : }
298 :
299 :
300 : - (NSDictionary *) cargoContractMarker:(OOSystemID)system
301 : {
302 : return [[[NSDictionary dictionaryWithObjectsAndKeys:
303 : [NSNumber numberWithInt:system], @"system",
304 : MISSION_DEST_LEGACY, @"name",
305 : @"orangeColor", @"markerColor",
306 : @"MARKER_SQUARE", @"markerShape",
307 : nil] retain] autorelease];
308 : }
309 :
310 :
311 : - (NSDictionary *) defaultMarker:(OOSystemID)system
312 : {
313 : return [[[NSDictionary dictionaryWithObjectsAndKeys:
314 : [NSNumber numberWithInt:system], @"system",
315 : MISSION_DEST_LEGACY, @"name",
316 : @"redColor", @"markerColor",
317 : @"MARKER_X", @"markerShape",
318 : nil] retain] autorelease];
319 : }
320 :
321 :
322 : - (NSDictionary *) validatedMarker:(NSDictionary *)marker
323 : {
324 : OOSystemID dest = [marker oo_intForKey:@"system"];
325 : // FIXME: parameters
326 : if (dest < 0 || dest > kOOMaximumSystemID)
327 : {
328 : return nil;
329 : }
330 : NSString *group = [marker oo_stringForKey:@"name" defaultValue:MISSION_DEST_LEGACY];
331 :
332 : return [[[NSDictionary dictionaryWithObjectsAndKeys:
333 : [NSNumber numberWithInt:dest], @"system",
334 : group, @"name",
335 : [marker oo_stringForKey:@"markerColor" defaultValue:@"redColor"], @"markerColor",
336 : [marker oo_stringForKey:@"markerShape" defaultValue:@"MARKER_X"], @"markerShape",
337 : [NSNumber numberWithFloat:[marker oo_floatForKey:@"markerScale" defaultValue:1.0]], @"markerScale",
338 : nil] retain] autorelease];
339 :
340 : }
341 :
342 :
343 : // Implements string expansion code [credits_number].
344 : - (NSString *) creditsFormattedForSubstitution
345 : {
346 : return OOStringFromDeciCredits([self deciCredits], YES, NO);
347 : }
348 :
349 :
350 : /* Implements string expansion code [_oo_legacy_credits_number].
351 :
352 : Literal uses of [credits_number] in legacy scripts are converted to
353 : [_oo_legacy_credits_number] in the script sanitizer. These are shown
354 : unlocalized because legacy scripts may use it for arithmetic.
355 : */
356 : - (NSString *) creditsFormattedForLegacySubstitution
357 : {
358 : OOCreditsQuantity tenthsOfCredits = [self deciCredits];
359 : unsigned long long integerCredits = tenthsOfCredits / 10;
360 : unsigned long long tenths = tenthsOfCredits % 10;
361 :
362 : return [NSString stringWithFormat:@"%llu.%llu", integerCredits, tenths];
363 : }
364 :
365 :
366 : // Implements string expansion code [commander_bounty].
367 : - (NSString *) commanderBountyAsString
368 : {
369 : return [NSString stringWithFormat:@"%i", [self legalStatus]];
370 : }
371 :
372 :
373 : // Implements string expansion code [commander_kills].
374 : - (NSString *) commanderKillsAsString
375 : {
376 : return [NSString stringWithFormat:@"%i", [self score]];
377 : }
378 :
379 :
380 : // utilising new keyconfig2.plist data
381 : - (NSString *) keyBindingDescription2:(NSString *)binding
382 : {
383 : if ([keyconfig2_settings objectForKey:binding] == nil)
384 : {
385 : // no such setting
386 : return nil;
387 : }
388 : NSArray *keyList = (NSArray*)[keyconfig2_settings objectForKey:binding];
389 : return [self getKeyBindingDescription:keyList];
390 : }
391 :
392 :
393 : - (NSString *) getKeyBindingDescription:(NSArray *) keyList
394 : {
395 : NSUInteger i = 0;
396 : NSMutableString *final = [NSMutableString string];
397 : for (i = 0; i < [keyList count]; i++) {
398 : if (i != 0) final = [NSMutableString stringWithFormat:@"%@ or ", final];
399 : NSDictionary *def = [keyList objectAtIndex:i];
400 : NSString *key = [def objectForKey:@"key"];
401 : OOKeyCode k_int = (OOKeyCode)[key integerValue];
402 : NSString *desc = [self keyCodeDescription:k_int];
403 : // 0 = key not set
404 : if (k_int != 0) {
405 : if ([[def objectForKey:@"mod2"] boolValue] == YES) final = [NSMutableString stringWithFormat:@"%@%@+", final, keyMod2Text];
406 : if ([[def objectForKey:@"mod1"] boolValue] == YES) final = [NSMutableString stringWithFormat:@"%@%@+", final, keyMod1Text];
407 : if ([[def objectForKey:@"shift"] boolValue] == YES) final = [NSMutableString stringWithFormat:@"%@%@+", final, keyShiftText];
408 : final = [NSMutableString stringWithFormat:@"%@%@", final, desc];
409 : }
410 : }
411 : return final;
412 : }
413 :
414 :
415 : - (NSString *) keyCodeDescription:(OOKeyCode)code
416 : {
417 : switch (code)
418 : {
419 : case 0:
420 : return DESC(@"oolite-keycode-unset");
421 : case 9:
422 : return DESC(@"oolite-keycode-tab");
423 : case 13:
424 : return DESC(@"oolite-keycode-enter");
425 : case 27:
426 : return DESC(@"oolite-keycode-esc");
427 : case 32:
428 : return DESC(@"oolite-keycode-space");
429 : case gvFunctionKey1:
430 : return DESC(@"oolite-keycode-f1");
431 : case gvFunctionKey2:
432 : return DESC(@"oolite-keycode-f2");
433 : case gvFunctionKey3:
434 : return DESC(@"oolite-keycode-f3");
435 : case gvFunctionKey4:
436 : return DESC(@"oolite-keycode-f4");
437 : case gvFunctionKey5:
438 : return DESC(@"oolite-keycode-f5");
439 : case gvFunctionKey6:
440 : return DESC(@"oolite-keycode-f6");
441 : case gvFunctionKey7:
442 : return DESC(@"oolite-keycode-f7");
443 : case gvFunctionKey8:
444 : return DESC(@"oolite-keycode-f8");
445 : case gvFunctionKey9:
446 : return DESC(@"oolite-keycode-f9");
447 : case gvFunctionKey10:
448 : return DESC(@"oolite-keycode-f10");
449 : case gvFunctionKey11:
450 : return DESC(@"oolite-keycode-f11");
451 : case gvArrowKeyRight:
452 : return DESC(@"oolite-keycode-right");
453 : case gvArrowKeyLeft:
454 : return DESC(@"oolite-keycode-left");
455 : case gvArrowKeyDown:
456 : return DESC(@"oolite-keycode-down");
457 : case gvArrowKeyUp:
458 : return DESC(@"oolite-keycode-up");
459 : case gvHomeKey:
460 : return DESC(@"oolite-keycode-home");
461 : case gvEndKey:
462 : return DESC(@"oolite-keycode-end");
463 : case gvInsertKey:
464 : return DESC(@"oolite-keycode-insert");
465 : case gvDeleteKey:
466 : return DESC(@"oolite-keycode-delete");
467 : case gvPageUpKey:
468 : return DESC(@"oolite-keycode-pageup");
469 : case gvPageDownKey:
470 : return DESC(@"oolite-keycode-pagedown");
471 : case gvNumberPadKey0:
472 : return DESC(@"oolite-keycode-numpad0");
473 : case gvNumberPadKey1:
474 : return DESC(@"oolite-keycode-numpad1");
475 : case gvNumberPadKey2:
476 : return DESC(@"oolite-keycode-numpad2");
477 : case gvNumberPadKey3:
478 : return DESC(@"oolite-keycode-numpad3");
479 : case gvNumberPadKey4:
480 : return DESC(@"oolite-keycode-numpad4");
481 : case gvNumberPadKey5:
482 : return DESC(@"oolite-keycode-numpad5");
483 : case gvNumberPadKey6:
484 : return DESC(@"oolite-keycode-numpad6");
485 : case gvNumberPadKey7:
486 : return DESC(@"oolite-keycode-numpad7");
487 : case gvNumberPadKey8:
488 : return DESC(@"oolite-keycode-numpad8");
489 : case gvNumberPadKey9:
490 : return DESC(@"oolite-keycode-numpad9");
491 : case gvPrintScreenKey:
492 : return DESC(@"oolite-keycode-printscreen");
493 : case gvPauseKey:
494 : return DESC(@"oolite-keycode-pause");
495 : case gvNumberPadKeyDivide:
496 : return DESC(@"oolite-keycode-numpad/");
497 : case gvNumberPadKeyEquals:
498 : return DESC(@"oolite-keycode-numpad=");
499 : case gvNumberPadKeyMinus:
500 : return DESC(@"oolite-keycode-numpad-");
501 : case gvNumberPadKeyMultiply:
502 : return DESC(@"oolite-keycode-numpad*");
503 : case gvNumberPadKeyPeriod:
504 : return DESC(@"oolite-keycode-numpad.");
505 : case gvNumberPadKeyPlus:
506 : return DESC(@"oolite-keycode-numpad+");
507 : case gvNumberPadKeyEnter:
508 : return DESC(@"oolite-keycode-numpadenter");
509 :
510 : default:
511 : return [NSString stringWithFormat:@"%C",code];
512 : }
513 : }
514 :
515 : - (NSString *) keyCodeDescriptionShort:(OOKeyCode)code
516 : {
517 : switch (code)
518 : {
519 : case 0:
520 : return DESC(@"oolite-keycode-short-unset");
521 : case 9:
522 : return DESC(@"oolite-keycode-short-tab");
523 : case 13:
524 : return DESC(@"oolite-keycode-short-enter");
525 : case 27:
526 : return DESC(@"oolite-keycode-short-esc");
527 : case 32:
528 : return DESC(@"oolite-keycode-short-space");
529 : case gvFunctionKey1:
530 : return DESC(@"oolite-keycode-short-f1");
531 : case gvFunctionKey2:
532 : return DESC(@"oolite-keycode-short-f2");
533 : case gvFunctionKey3:
534 : return DESC(@"oolite-keycode-short-f3");
535 : case gvFunctionKey4:
536 : return DESC(@"oolite-keycode-short-f4");
537 : case gvFunctionKey5:
538 : return DESC(@"oolite-keycode-short-f5");
539 : case gvFunctionKey6:
540 : return DESC(@"oolite-keycode-short-f6");
541 : case gvFunctionKey7:
542 : return DESC(@"oolite-keycode-short-f7");
543 : case gvFunctionKey8:
544 : return DESC(@"oolite-keycode-short-f8");
545 : case gvFunctionKey9:
546 : return DESC(@"oolite-keycode-short-f9");
547 : case gvFunctionKey10:
548 : return DESC(@"oolite-keycode-short-f10");
549 : case gvFunctionKey11:
550 : return DESC(@"oolite-keycode-short-f11");
551 : case gvArrowKeyRight:
552 : return DESC(@"oolite-keycode-short-right");
553 : case gvArrowKeyLeft:
554 : return DESC(@"oolite-keycode-short-left");
555 : case gvArrowKeyDown:
556 : return DESC(@"oolite-keycode-short-down");
557 : case gvArrowKeyUp:
558 : return DESC(@"oolite-keycode-short-up");
559 : case gvHomeKey:
560 : return DESC(@"oolite-keycode-short-home");
561 : case gvEndKey:
562 : return DESC(@"oolite-keycode-short-end");
563 : case gvInsertKey:
564 : return DESC(@"oolite-keycode-short-insert");
565 : case gvDeleteKey:
566 : return DESC(@"oolite-keycode-short-delete");
567 : case gvPageUpKey:
568 : return DESC(@"oolite-keycode-short-pageup");
569 : case gvPageDownKey:
570 : return DESC(@"oolite-keycode-short-pagedown");
571 : case gvNumberPadKey0:
572 : return DESC(@"oolite-keycode-short-numpad0");
573 : case gvNumberPadKey1:
574 : return DESC(@"oolite-keycode-short-numpad1");
575 : case gvNumberPadKey2:
576 : return DESC(@"oolite-keycode-short-numpad2");
577 : case gvNumberPadKey3:
578 : return DESC(@"oolite-keycode-short-numpad3");
579 : case gvNumberPadKey4:
580 : return DESC(@"oolite-keycode-short-numpad4");
581 : case gvNumberPadKey5:
582 : return DESC(@"oolite-keycode-short-numpad5");
583 : case gvNumberPadKey6:
584 : return DESC(@"oolite-keycode-short-numpad6");
585 : case gvNumberPadKey7:
586 : return DESC(@"oolite-keycode-short-numpad7");
587 : case gvNumberPadKey8:
588 : return DESC(@"oolite-keycode-short-numpad8");
589 : case gvNumberPadKey9:
590 : return DESC(@"oolite-keycode-short-numpad9");
591 : case gvPrintScreenKey:
592 : return DESC(@"oolite-keycode-short-printscreen");
593 : case gvPauseKey:
594 : return DESC(@"oolite-keycode-short-pause");
595 : case gvNumberPadKeyDivide:
596 : return DESC(@"oolite-keycode-short-numpad/");
597 : case gvNumberPadKeyEquals:
598 : return DESC(@"oolite-keycode-short-numpad=");
599 : case gvNumberPadKeyMinus:
600 : return DESC(@"oolite-keycode-short-numpad-");
601 : case gvNumberPadKeyMultiply:
602 : return DESC(@"oolite-keycode-short-numpad*");
603 : case gvNumberPadKeyPeriod:
604 : return DESC(@"oolite-keycode-short-numpad.");
605 : case gvNumberPadKeyPlus:
606 : return DESC(@"oolite-keycode-short-numpad+");
607 : case gvNumberPadKeyEnter:
608 : return DESC(@"oolite-keycode-short-numpadenter");
609 : default:
610 : return [NSString stringWithFormat:@"%C",code];
611 : }
612 : }
613 :
614 : @end
615 :
616 :
617 0 : Vector OOGalacticCoordinatesFromInternal(NSPoint internalCoordinates)
618 : {
619 : return (Vector){ (float)internalCoordinates.x * 0.4f, (float)internalCoordinates.y * 0.2f, 0.0f };
620 : }
621 :
622 :
623 0 : NSPoint OOInternalCoordinatesFromGalactic(Vector galacticCoordinates)
624 : {
625 : return (NSPoint){ (float)galacticCoordinates.x * 2.5f, (float)galacticCoordinates.y * 5.0f };
626 : }
|