-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpostOrders.php
executable file
·847 lines (754 loc) · 34.2 KB
/
postOrders.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
#!/usr/bin/php -q
<?php
###
# Creates a new data file from an old one
###
# Stuffs the purchase & construction display
# Performs basic movement
# - Does not check for collisions with others
# - Does not check for movement to a neighbor sector
# Adds unknown location to colonies
# Adds new unknown locations for new sector
# Adds raiding scenarios
###
if( ! isset($argv[1]) )
{
echo "\nHandles post-orders items for a player position\nThis is used after the first turn segment.\n\n";
echo "Called by:\n";
echo " ".$argv[0]." DATA_FILE [NEW FILE NAME]\n";
exit(1);
}
###
# Configuration
###
$AUTO_ROLL_EMPTY_SYSTEMS = true; // if true, calls $SYSTEM_ROLLER for any new explorations
$EXPLAIN_RAIDS = false; // if true, explains the chances of a successful raid
$MAKE_CHECKLIST = false; // if true, adds a turn checklist to the events
$MAPPOINTS_NAME = 3; // Index in mapPoints array of datafile for the location name
$MAPPOINTS_OWNER = 2; // Index in mapPoints array of datafile for the owning position (empire type)
$mapX = 30; // mapPoints increment for the x-coord
$mapY = 35; // mapPoints increment for the y-coord
$SHOW_ALL_RAIDS = true; // if true, shows failed raids as events
$SYSTEM_ROLLER = "./system_data.php"; // script to generate each system
$SYSTEM_ROLLER_SEPERATOR = "•"; // HTML entity that prepends the output of $SYSTEM_ROLLER
###
# Initialization
###
$inputData = array(); // PHP variable of the JSON data
$newFileName = $argv[1]; // save file filename
$checklist = array(); // list of things that need to be done
if( isset($argv[2]) )
$newFileName = $argv[2];
else if( strrpos( $argv[1], "/" ) !== false )
$newFileName = substr( $argv[1], strrpos( $argv[1], "/" )+1 );
include( "./postFunctions.php" );
include( $SYSTEM_ROLLER );
###
# Generate Input
###
$inputData = extractJSON( $argv[1] );
if( $inputData === false ) // leave if there was an error loading the file
exit(1);
// get the lookup tables
list( $byColonyName, $byColonyOwner, $byFleetName, $byFleetLocation, $byFleetUnits, $byMapLocation, $byMapOwner, $byDesignator ) = makeLookUps($inputData);
$byRaidLocation = array(); // empty for now. filled when calculating places being raided
###
# Make the middle-turn modifications
###
// stuff the purchases and underConstruction array
$inputData["purchases"] = array(); // empty the purchases array
$inputData["underConstruction"] = array(); // empty the construction array
// get the orders for things that are purchased
$orderKeys = array_merge( findOrder( $inputData, "build_unit" ), findOrder( $inputData, "research" ), findOrder( $inputData, "convert" ) );
if( isset($orderKeys[0]) ) // if there are none of these orders, then skip
{
foreach( $orderKeys as $key )
{
// research investment
if( strtolower($inputData["orders"][ $key ]["type"]) == "research" )
{
// Determine if this would cause overspending
if( getLeftover( $inputData ) < intval($inputData["orders"][ $key ]["note"]) )
{
$inputData["events"][] = array(
"event"=>"Research order cancelled due to overspending",
"time"=>"Turn ".$inputData["game"]["turn"],
"text"=>""
);
echo "Research order cancelled due to overspending.\n";
continue; // go on to the next order
}
// add to the purchases
$inputData["purchases"][] = array( "name"=>"Research","cost"=>intval($inputData["orders"][ $key ]["note"]) );
}
elseif( strtolower($inputData["orders"][ $key ]["type"]) == "convert" ) // unit conversions
{
// How to know which unit to convert?
// need to define the order to convert
/*
$unitCost = 0;
$unitRebate = 0;
// find the cost of the old unit
foreach( $inputData["unitList"] as $hull )
if( strtolower($hull["ship"]) == strtolower($inputData["orders"][ $orderKeys ]["reciever"]) )
{
$unitRebate = $hull["cost"];
break; // quit the loop. We found our unit.
}
// find the cost of the new unit
foreach( $inputData["unitList"] as $hull )
if( strtolower($hull["ship"]) == strtolower($inputData["orders"][ $orderKeys ]["target"]) )
{
$unitCost = $hull["cost"];
break; // quit the loop. We found our unit.
}
if( $unitRebate > $unitCost )
$unitCost = 0; // the rebate cannot give back money if larger than the cost
else
$unitCost -= $unitRebate
// find the location of the unit
foreach( $inputData["fleet"] as $item )
foreach( $item["units"] as $hull )
{
}
$inputData["purchases"][] = array( "name"=>"Convert '".$inputData["orders"][ $orderKey ]["reciever"]."' to '".$inputData["orders"][ $orderKey ]["target"]."'","cost"=>$unitCost );
$inputData["underConstruction"][] = array( "location"=>$inputData["orders"][ $orderKey ]["target"],"unit"=>$inputData["orders"][ $orderKey ]["reciever"] );
*/
}
else // unit purchase
{
// find the cost of the unit
$unitCost = $inputData["unitList"][ $byDesignator[ $inputData["orders"][ $key ]["reciever"] ] ]["cost"];
// Determine if this would cause overspending
if( getLeftover( $inputData ) < $unitCost )
{
$inputData["events"][] = array(
"event"=>"Build order of ".$inputData["orders"][ $key ]["reciever"]." cancelled due to overspending",
"time"=>"Turn ".$inputData["game"]["turn"],
"text"=>""
);
echo "Build order of ".$inputData["orders"][ $key ]["reciever"]." cancelled due to overspending.\n";
continue; // go on to the next order
}
$inputData["purchases"][] = array( "name"=>$inputData["orders"][ $key ]["reciever"],"cost"=>$unitCost );
$inputData["underConstruction"][] = array( "location"=>$inputData["orders"][ $key ]["target"],"unit"=>$inputData["orders"][ $key ]["reciever"] );
}
}
}
###
# Process movement orders
###
// find the movement orders and re-locate the fleets
$orderKeys = findOrder( $inputData, "move" );
// make sure there are move orders
// also ensure there are fleets to move
if( isset($orderKeys[0]) && isset($inputData["fleets"]) && ! empty($inputData["fleets"]) )
{
foreach( $orderKeys as $orderKey ) // go through the movement orders
{
# Verifies that the target location in unknownMovementPlaces or colonies is valid
# Removes it from unknownMoementPlaces, if the location is there
# It would verify the initial fleet location and hte target location are immediate neighbors,
# but there is currently no way to know they are connected.
# Updates the location of the fleet to match the destination
// convenience variable for the fleet's location
$fleetLocation = $inputData["orders"][ $orderKey ]["target"];
// convenience variable for the fleet's name
$fleetName = $inputData["orders"][ $orderKey ]["reciever"];
// flag for if the location is known
// if it remains false, the location may not be a location that the position knows about
$flag = false;
// if the location is in the unknownMovementPlaces, remove it
$unknownKey = array_search( $fleetLocation, $inputData["unknownMovementPlaces"] );
if( $unknownKey !== false )
{
$flag = true; // we found the location in unknownMovementPlaces
// update the fleet location with the proper case
$fleetLocation = $inputData["unknownMovementPlaces"][$unknownKey];
// remove the entry
unset( $inputData["unknownMovementPlaces"][$unknownKey] );
}
// if the location is in colonies, then it is a valid order
else if( isset( $byColonyName[ $fleetLocation ] ) )
$flag = true; // we found the location in colonies
if( ! $flag )
{
echo "Fleet '".$fleetName;
echo "' ordered to move to '$fleetLocation', but location is not \nfound in ";
echo "unknown, movable locations. Perhaps the order is mispelled.\n";
$inputData["events"][] = array("event"=>"move order failed","time"=>"Turn ".$inputData["game"]["turn"],
"text"=>"Fleet '$fleetName' ordered to move to '$fleetLocation', but "
."location is not found in unknown, movable locations. Perhaps "
."the order is mispelled.\n"
);
}
// update the location of the fleet to match the target location
$inputData["fleets"][ $byFleetName[ $fleetName ] ]["location"] = $fleetLocation;
###
# Exploration
###
$flag = false; // reset the flag
// if the location is not in colonies, add it
if( ! isset($byColonyName[ $fleetLocation ]) )
{
// roll for newly-explored systems, if set to do so
if( $AUTO_ROLL_EMPTY_SYSTEMS )
{
echo "\nRolling for system at '".$fleetLocation."'.\n";
$explorationData = VBAMExploration(); // get the output from the $SYSTEM_ROLLER command
$output = array_shift( $explorationData ); // the text output was the first entry
// print the result of $SYSTEM_ROLLER with $SYSTEM_ROLLER_SEPERATOR prepended to each line
echo html_entity_decode( $SYSTEM_ROLLER_SEPERATOR );
echo str_replace( "\n", "\n".html_entity_decode($SYSTEM_ROLLER_SEPERATOR)." ", rtrim($output) );
echo "\n\n";
// Ask if we modify the system per the above script
echo "Use this entry in the data file? (Y/N) ";
$answer = rtrim( fgets( STDIN ) );
if( strtolower( $answer ) == "y" )
{
$explorationData["name"] = $fleetLocation;
$inputData["colonies"][] = $explorationData;
}
else
{
echo "Need to create the stats for the system at '".$fleetLocation."'\n";
$inputData["events"][] = array(
"event"=>"Need to create the stats for the system at '".$fleetLocation,
"time"=>"Turn ".$inputData["game"]["turn"],
"text"=>""
);
$inputData["colonies"][] = array("name"=>$fleetLocation, "census"=>0,
"owner"=>"", "morale"=>0, "raw"=>0,"prod"=>0, "capacity"=>0,
"intel"=>0, "fixed"=>array(), "notes"=>""
);
}
}
}
if( ! $AUTO_ROLL_EMPTY_SYSTEMS )
{
echo "Need to create the stats for the system at '".$fleetLocation."'\n";
$inputData["events"][] = array(
"event"=>"Need to create the stats for the system at '".$fleetLocation,
"time"=>"Turn ".$inputData["game"]["turn"],
"text"=>""
);
$inputData["colonies"][] = array("name"=>$fleetLocation, "census"=>0,
"owner"=>"", "morale"=>0, "raw"=>0,"prod"=>0, "capacity"=>0,
"intel"=>0, "fixed"=>array(), "notes"=>""
);
}
$flag = false; // reset the flag
// update MapPoints
// format is [ y , x, color, name ]
// Make a copy of the map so we can add to the array without iterating over the new entries
$mapCopy = $inputData["mapPoints"];
foreach( $mapCopy as $key=>$value )
{
// Skip if this value of mapPoints is not the location of interest
// case insensitive
if( $value[3] != $fleetLocation )
continue;
// update the owner of this location, with the 'colonies' array being the standard
foreach( $inputData["colonies"] as $colonyData )
{
// skip of this colony is not this location
if( $colonyData["name"] != $inputData["mapPoints"][$key][$MAPPOINTS_NAME] )
continue;
if( $colonyData["owner"] != $inputData["mapPoints"][$key][$MAPPOINTS_OWNER] )
$inputData["mapPoints"][$key][2] = $colonyData["owner"];
}
// find the neighbor X/Y values of this location
$neighbors = array(); // list of neighbor coords
$neighbors["A"] = array( ($value[0]-$mapY), $value[1] ); // previous Y, same X
$neighbors["D"] = array( ($value[0]+$mapY), $value[1] ); // next Y, same X
// find if the location is even/odd
if( $value[1] % ($mapX*2) > 0 ) // Dir B/F on same Y as location
{
$neighbors["B"] = array( $value[0], ($value[1]+$mapX) ); // same Y, next X
$neighbors["C"] = array( ($value[0]+$mapY), ($value[1]+$mapX) ); // next Y, next X
$neighbors["E"] = array( ($value[0]+$mapY), ($value[1]-$mapX) ); // next Y, previous X
$neighbors["F"] = array( $value[0], ($value[1]-$mapX) ); // same Y, previous X
}
else // Dir C/E on same Y as location
{
$neighbors["B"] = array( ($value[0]-$mapY), ($value[1]+$mapX) ); // previous Y, next X
$neighbors["C"] = array( $value[0], ($value[1]+$mapX) ); // same Y, next X
$neighbors["E"] = array( $value[0], ($value[1]-$mapX) ); // same Y, previous X
$neighbors["F"] = array( ($value[0]-$mapY), ($value[1]-$mapX) ); // previous Y, previous X
}
// find and remove neighbors in MapPoints
// what remains is not in MapPoints
foreach( $inputData["mapPoints"] as $neighborFind )
{
if( isset($neighbors["A"]) && $neighborFind[0] == $neighbors["A"][0] && $neighborFind[1] == $neighbors["A"][1] )
unset( $neighbors["A"] );
if( isset($neighbors["B"]) && $neighborFind[0] == $neighbors["B"][0] && $neighborFind[1] == $neighbors["B"][1] )
unset( $neighbors["B"] );
if( isset($neighbors["C"]) && $neighborFind[0] == $neighbors["C"][0] && $neighborFind[1] == $neighbors["C"][1] )
unset( $neighbors["C"] );
if( isset($neighbors["D"]) && $neighborFind[0] == $neighbors["D"][0] && $neighborFind[1] == $neighbors["D"][1] )
unset( $neighbors["D"] );
if( isset($neighbors["E"]) && $neighborFind[0] == $neighbors["E"][0] && $neighborFind[1] == $neighbors["E"][1] )
unset( $neighbors["E"] );
if( isset($neighbors["F"]) && $neighborFind[0] == $neighbors["F"][0] && $neighborFind[1] == $neighbors["F"][1] )
unset( $neighbors["F"] );
}
// add the new entry
foreach( $neighbors as $newKey=>$newValue )
{
$inputData["mapPoints"][] = array( $newValue[0], $newValue[1], "", $value[3].$newKey );
// Add this entry to unknownMovementPlaces
$inputData["unknownMovementPlaces"][] = $value[3].$newKey;
}
break; // skip to the end, since we found the location
}
}
$inputData["unknownMovementPlaces"] = array_values( $inputData["unknownMovementPlaces"] );
} // end of movement-order handling
// Re-order Colonies, based on name
usort( $inputData["colonies"], "colonyNameSort" );
// Re-order mapPoints, based on location
usort( $inputData["mapPoints"], "mapLocSort" );
// update the lookup tables
list( $byColonyName, $byColonyOwner, $byFleetName, $byFleetLocation, , $byMapLocation, $byMapOwner, ) = makeLookUps( $inputData, true );
###
# Add Checklist
# - Placed here so raid-output is placed correct
###
if( $MAKE_CHECKLIST )
{
$checklist = array();
// Fill events with a checklist
$checklist[] = "Checklist: Intel";
$checklist[] = "Checklist: Diplomatic shifts for NPEs";
$checklist[] = "Checklist: Hostility checks for NPEs";
$checklist[] = "Checklist: NPEs offer treaties";
$checklist[] = "Checklist: Movement";
$checklist[] = "Checklist: Check supply";
$checklist[] = "Checklist: Raiding";
foreach( $checklist as $entry )
$inputData["events"][] = array("event"=>$entry,"time"=>"Turn ".$inputData["game"]["turn"],"text"=>"");
unset( $checklist );
}
###
# Load / unload units (colony fleets, troop transports)
# Note: This is post-movement, before combat
# Load Order: {"type":"load","reciever":"Colony Fleet w\/ Colony-1","target":"Census","note":"1"}
###
// Find any load orders
$orderKeys = findOrder( $inputData, "load" );
if( isset($orderKeys[0]) ) // is there at least one instance?
{
foreach( $orderKeys as $key )
{
$loadAmt = (int) $inputData["orders"][$key]["note"];
$reciever = (string) $inputData["orders"][$key]["reciever"];
$target = (string) $inputData["orders"][$key]["target"];
// Keep the load amount a single digit
if( $loadAmt > 9 )
{
$loadAmt = 9;
$inputData["orders"][$key]["note"] = 9; // truncate the given order
echo "Order given to load '$reciever' with ".$inputData["orders"][$key]["note"];
echo " of '$target'. Amount truncated to 9.\n";
}
// convenience variable. Error string that identifies order that is wrong
$loadErrorString = "Order given to load '$reciever' with $loadAmt of '$target'. ";
$fleet = -1; // key to the fleet array
$fleetLoc = -1; // key to colonies array
$isGroundUnit = false; // determines if a unit being loaded is a ground unit
// determine if this is a ground unit being loaded
if( isset( $byDesignator[ $target ] )
&& $inputData["unitList"][ $byDesignator[ $target ] ]["design"] == "ground unit"
)
$isGroundUnit = true;
// find the fleet
foreach( $byFleetName as $fleetName=>$fleetKey )
if( str_ends_with( $reciever, $fleetName ) )
$fleet = $fleetKey;
if( $fleet == -1 )
{
echo $loadErrorString."Could not find fleet.\n";
exit(1);
}
// skip if this fleet location cannot be found
if( ! isset( $byColonyName[ $inputData["fleets"][$fleet]["location"] ] ) )
{
echo $loadErrorString."'. Location of fleet is not a colony.\n";
$inputData["events"][] = array("event"=>"Load order failed","time"=>"Turn ".$inputData["game"]["turn"],
"text"=>$loadErrorString."Location of fleet is not a colony.\n");
continue;
}
else
{
$fleetLoc = $byColonyName[ $inputData["fleets"][$fleet]["location"] ]; // find fleet location
}
// determine if this colony is owned by the player
if( $inputData["colonies"][$fleetLoc]["owner"] != $inputData["empire"]["empire"] )
{
echo $loadErrorString."'. This player does not own this colony.\n";
$inputData["events"][] = array("event"=>"Load order failed","time"=>"Turn ".$inputData["game"]["turn"],
"text"=>$loadErrorString."This player does not own this colony.\n");
continue;
}
// find amt of the supply trait in this fleet
$supplyAmt = getFleetSupplyValue( $inputData, $inputData["fleets"][$fleet]["units"] );
if( $supplyAmt == 0 ) // skip if this fleet has no supply trait
{
echo $loadErrorString."'. Fleet has no supply trait.\n";
$inputData["events"][] = array("event"=>"Load order failed","time"=>"Turn ".$inputData["game"]["turn"],
"text"=>$loadErrorString."Fleet has no supply trait.\n");
continue;
}
// find supply amt already used in this fleet
$supplyUsed = getFleetloadedValue( $inputData["fleets"][$fleet] );
// skip if the fleet cannot hold the unit
if( $supplyAmt - $supplyUsed < ( 10 * $loadAmt ) )
{
echo $loadErrorString."'. Loading $loadAmt would overload fleet.\n";
$inputData["events"][] = array("event"=>"Load order failed","time"=>"Turn ".$inputData["game"]["turn"],
"text"=>$loadErrorString."Loading $loadAmt would overload fleet.\n");
continue;
}
// Load Census
if( strtolower($inputData["orders"][$key]["target"]) == "census" )
{
// skip if there is not enough Census to load
if( $inputData["colonies"][$fleetLoc]["census"] <= $loadAmt+1 )
{
echo $loadErrorString."'. Loading $loadAmt of Census would empty the colony.\n";
$inputData["events"][] = array("event"=>"Load order failed","time"=>"Turn ".$inputData["game"]["turn"],
"text"=>$loadErrorString."Loading $loadAmt of Census would empty the colony.\n");
continue;
}
// Add Census to fleet
$inputData["fleets"][$fleet]["notes"] .= "$loadAmt Census loaded.";
// Do not remove Census from location
// It is needed for showing the start-of-turn economics
// The UI shows that the Census will be deducted at the end of turn
/*
// remove Census from location
$inputData["colonies"][$fleetLoc]["census"] -= $loadAmt;
// deal with maybe having to much Morale
if( $inputData["colonies"][$fleetLoc]["morale"] > $inputData["colonies"][$fleetLoc]["census"] )
$inputData["colonies"][$fleetLoc]["morale"] = $inputData["colonies"][$fleetLoc]["census"];
*/
// finished with this load order
continue;
}
// Load ground units
if( $isGroundUnit )
{
$unitCount = 0;
// skip if there is not enough of this ground unit to load
foreach( $inputData["colonies"][$fleetLoc]["fixed"] as $fixedKey=>$fixed )
if( strtolower($inputData["orders"][$key]["target"]) == strtolower($fixed) )
$unitCount++;
if( $unitCount < $loadAmt )
{
echo $loadErrorString."'. Not enough $target are present at colony.\n";
$inputData["events"][] = array("event"=>"Load order failed","time"=>"Turn ".$inputData["game"]["turn"],
"text"=>$loadErrorString."'. Not enough $target are present at colony.\n");
continue;
}
// Add unit to fleet
$inputData["fleets"][$fleet]["notes"] .= "$loadAmt $target loaded.";
// remove unit from location
foreach( $inputData["colonies"][$fleetLoc]["fixed"] as $fixedKey=>$fixed )
{
if( strtolower($target) == strtolower($fixed) && $loadAmt > 0 )
{
unset( $inputData["colonies"][$fleetLoc]["fixed"][$fixedKey] );
$loadAmt--;
}
}
// re-index the fixed-unit array
$inputData["colonies"][$fleetLoc]["fixed"] = array_values( $inputData["colonies"][$fleetLoc]["fixed"] );
// finished with this load order
continue;
}
echo $loadErrorString."'. Unit not loaded.\n";
$inputData["events"][] = array("event"=>"Load order failed","time"=>"Turn ".$inputData["game"]["turn"],"text"=>$loadErrorString."Unit not loaded.\n");
}
// $inputData["orders"] = array_values( $inputData["orders"] ); // re-index the orders to close up gaps caused by invalid orders
}
/***
Unloading uses the same process, but with reverse effects
***/
// Find any unload orders
$orderKeys = findOrder( $inputData, "unload" );
if( isset($orderKeys[0]) ) // is there at least one instance?
{
foreach( $orderKeys as $key )
{
$loadAmt = (int) $inputData["orders"][$key]["note"];
$reciever = (string) $inputData["orders"][$key]["reciever"];
$target = (string) $inputData["orders"][$key]["target"];
// Keep the unload amount a single digit
if( $loadAmt > 9 )
{
$loadAmt = 9;
$inputData["orders"][$key]["note"] = 9; // truncate the given order
echo "Order given to unload '$reciever' with ".$inputData["orders"][$key]["note"];
echo " of '$target'. Amount truncated to 9.\n";
}
// convenience variable. Error string that identifies order that is wrong
$loadErrorString = "Order given to unload '$reciever' with $loadAmt of '$target'. ";
$fleet = -1; // key of the fleet array that is being loaded
$isGroundUnit = false; // determines if a unit being loaded is a ground unit
// determine if this is a ground unit being unloaded
if( isset( $byDesignator[ $target ] )
&& $inputData["unitList"][ $byDesignator[ $target ] ]["design"] == "ground unit"
)
$isGroundUnit = true;
// find the fleet
foreach( $inputData["fleets"] as $fleetKey=>$value )
if( str_ends_with( $reciever, $value["name"] ) )
$fleet = $fleetKey;
if( $fleet == -1 )
{
echo $loadErrorString."Could not find fleet.\n";
// do not remove order, because exiting the script
exit(1);
}
$success = preg_match( "/(\d) $reciever loaded/i", $loadAmt, $matches );
$amtLoaded = (int) $matches[1];
if( ! $success || $amtLoaded < 1 )
{
echo $loadErrorString."Fleet does not carry any $target.\n";
// do not remove order, because exiting the script
exit(1);
}
// skip if there is not enough to unload
if( $amtLoaded >= $loadAmt )
{
echo $loadErrorString."'. The fleet does not carry enough. It only has $amtLoaded.\n";
$inputData["events"][] = array("event"=>"Load order failed","time"=>"Turn ".$inputData["game"]["turn"],
"text"=>$loadErrorString."The fleet does not carry enough. It only has $amtLoaded.\n");
continue;
}
// skip if this fleet location cannot be found
if( ! isset( $byColonyName[ $inputData["fleets"][$fleet]["location"] ] ) )
{
echo $loadErrorString."'. Location of fleet is not a colony.\n";
$inputData["events"][] = array("event"=>"Load order failed","time"=>"Turn ".$inputData["game"]["turn"],
"text"=>$loadErrorString."Location of fleet is not a colony.\n");
continue;
}
else
{
$fleetLoc = $byColonyName[ $inputData["fleets"][$fleet]["location"] ]; // find fleet location
}
// Unload Census
if( strtolower($inputData["orders"][$key]["target"]) == "census" )
{
// determine if this colony is owned by the player
if( $inputData["colonies"][$fleetLoc]["owner"] != $inputData["empire"]["empire"] )
{
echo $loadErrorString."'. This player does not own this colony.\n";
$inputData["events"][] = array("event"=>"Load order failed","time"=>"Turn ".$inputData["game"]["turn"],
"text"=>$loadErrorString."This player does not own this colony.\n");
continue;
}
/*
// Remove Census from fleet
$inputData["fleets"][$fleet]["notes"] = str_replace(
"$loadAmt Census loaded.",
"",
$inputData["fleets"][$fleet]["notes"]
);
// add Census to location
$inputData["colonies"][$fleetLoc]["census"] += $loadAmt;
*/
// finished with this unload order
continue;
}
// Unload ground units
if( $isGroundUnit )
{
// Remove unit to fleet
$inputData["fleets"][$fleet]["notes"] = str_replace(
"$loadAmt $target loaded.",
"",
$inputData["fleets"][$fleet]["notes"]
);
// add unit to location
for( $i=$loadAmt; $i=0; $i-- )
$inputData["colonies"][$fleetLoc]["fixed"][] = $inputData["orders"][$key]["target"];
// re-index the fixed-unit array
$inputData["colonies"][$fleetLoc]["fixed"] = array_values( $inputData["colonies"][$fleetLoc]["fixed"] );
// finished with this unload order
continue;
}
echo $loadErrorString."Unit not unloaded.\n";
$inputData["events"][] = array("event"=>"Load order failed","time"=>"Turn ".$inputData["game"]["turn"],
"text"=>$loadErrorString."Unit not unloaded.\n");
}
// $inputData["orders"] = array_values( $inputData["orders"] ); // re-index the orders to close up gaps caused by invalid orders
}
###
# Add raids
# Note: This is post-movement, during combat
###
$raidPlaces = array();
### Need to capture places not owned by this empire, who have civilian fleets
// Mark locations owned by this player as raid locations if empty of naval elements
// Count naval EP value at each location
foreach( $byColonyOwner[ $inputData["empire"]["empire"] ] as $item )
{
$locationName = $inputData["colonies"][ $item ]["name"]; // convenience variable
$navalCost = 0; // EP cost of ships at this location
$civvieCount = 0; // number of civilian units here
// count the units present only if there are fleets here
if( isset( $byFleetLocation[ $locationName ] ) )
// count the ships here (civvie count, naval cost)
foreach( $byFleetLocation[ $locationName ] as $index )
foreach( $inputData["fleets"][$index]["units"] as $hull )
{
// count if a civilian unit
if( in_array( $hull, $CIVILIAN_FLEETS ) )
{
$civvieCount++;
continue;
}
// get EP cost if a naval unit
$navalCost += $inputData["unitList"][ $byDesignator[$hull] ]["cost"];
}
// add to raid places if no fleet EP is here or some civilian craft
if( $navalCost == 0 || $civvieCount > 0 )
{
$raidPlaces[] = array( "civCount" => $civvieCount,
"location"=> $locationName,
"naval"=> $navalCost
);
$byRaidLocation[$locationName] = array_key_last($raidPlaces);
}
}
// find places that contain fleets but are un-owned by this player
// note that these arrays have keys that are colony names
$lonelyRaids = array_diff_key( $byFleetLocation, $byRaidLocation );
// iterate through those fleets, finding locations that contain civilian fleets
foreach( $lonelyRaids as $locationName=>$fleetList )
{
foreach( $fleetList as $index )
{
$navalCost = 0; // EP cost of ships at this location
$civvieCount = 0; // number of civilian units here
// count the ships here (civvie count, naval cost)
foreach( $inputData["fleets"][$index]["units"] as $hull )
{
// count if a civilian unit
if( in_array( $hull, $CIVILIAN_FLEETS ) )
{
$civvieCount++;
continue;
}
// get EP cost if a naval unit
$navalCost += $inputData["unitList"][ $byDesignator[$hull] ]["cost"];
}
// add to raid places if civilian ships are in this fleet
// Other fleets might have more naval units, but they become reinforcements
if( $civvieCount > 0 )
$raidPlaces[] = array( "civCount" => $civvieCount,
"location"=> $locationName,
"naval"=> $navalCost
);
$byRaidLocation[$locationName] = array_key_last($raidPlaces);
}
}
// Calculate the raids
foreach( $raidPlaces as $place )
{
$chance = 20; // base chance to get a raid
$civChance = 0; // chance from additional civilian ships
$navalChance = 0; // chance reduction from naval ships
$intelChance = 0; // chance reduction from intel ops
$rand = mt_rand(1,100); // determination of raid occurance
// If there is more than one civilian fleet, increase the chance of a raid by 20% per additional
// The first civilian fleet allows the chance of a raid
if( $place["civCount"] > 1 )
$civChance = ($place["civCount"]-1) * 20;
if( $place["naval"] > 0 )
$navalChance += 5; // 5% off for more than 0 construction value
if( $place["naval"] > 8 )
$navalChance += 5; // total of 10% off for more than 8 construction value
if( $place["naval"] > 12 )
$navalChance = 20 * intval($place["naval"] / 12); // 20% off the chance for every 12 construction value
// find out if intel was used to prevent this
$orderKeys = findOrder( $inputData, "intel" );
if( isset($orderKeys[0]) )
foreach( $orderKeys as $key )
if( $inputData["orders"][$key]["reciever"] == "Reduce Raiding" && $inputData["orders"][$key]["target"] == $place["location"] )
// reduce chances by 10% per intel used
$intelChance = 10 * intval($inputData["orders"][$key]["note"]);
$chance += $civChance - $navalChance - $intelChance;
if( $rand <= $chance )
{
$raidAmt = mt_rand(1,3) * mt_rand(1,6);
$text = "A raid struck '".$place["location"]."'. There was a $chance% chance and a $rand was rolled. ";
$text .= "It is raided with $raidAmt construction value of raiders. If there is a civilian fleet present, ";
$text .= "that is the target of the raid. One fleet at that location may participate as reinforcements. ";
$text .= "If there are no civilian units to raid, then the fixed installation that are raided.";
if( $EXPLAIN_RAIDS )
{
$text .= " There were ".$place["civCount"]." civilian craft, for a base chance of ".(20+$civChance);
$text .= "% and ".$place["naval"]." EP in naval units, which reduced the chance by $navalChance%. ";
$text .= "Intel (if used) dropped chances by $intelChance%.";
}
$inputData["events"][] = array("event"=>"A raid in '".$place["location"]."' happened.","time"=>"Turn ".$inputData["game"]["turn"],"text"=>$text);
}
else
{
$text = "There was no raid in '".$place["location"]."'. There was a $chance% chance and a $rand was rolled.";
if( $EXPLAIN_RAIDS )
{
$text .= " There were ".$place["civCount"]." civilian craft, for a base chance of ".(20+$civChance);
$text .= "% and ".$place["naval"]." EP in naval units, which reduced the chance by $navalChance%. ";
$text .= "Intel (if used) dropped chances by $intelChance%.";
}
$inputData["events"][] = array("event"=>"A raid failed in '".$place["location"]."'.","time"=>"Turn ".$inputData["game"]["turn"],"text"=>$text);
}
}
// make all of the orders section into non-drop-down menus
foreach( array_keys( $inputData["orders"] ) as $key )
$inputData["orders"][$key]["perm"] = 1;
// Note: Leave $inputData["game"]["blankOrders"] alone. The next segment of the turn needs these drop-downs.
###
# Add Checklist
# - Placed here so raid-output is placed correct
###
if( $MAKE_CHECKLIST )
{
// Fill events with a checklist
$checklist[] = "Checklist: Combat";
foreach( $checklist as $entry )
$inputData["events"][] = array("event"=>$entry,"time"=>"Turn ".$inputData["game"]["turn"],"text"=>"");
unset( $checklist );
}
###
# Write out the file
###
writeJSON( $inputData, $newFileName );
exit(0); // all done
###
# Sorting function to be used on the colonies data structure
###
function colonyNameSort( $a, $b )
{
return strcmp($a["name"], $b["name"]);
}
###
# Sorting function to be used on the mapPoints data structure
###
function mapLocSort( $a, $b )
{
if( intval($a[0]) == intval($b[0]) )
{
if( intval($a[1]) == intval($b[1]) )
return 0;
else
return ( intval($a[1]) > intval($b[1])) ? +1 : -1;
}
else
return ( intval($a[0]) > intval($b[0])) ? +1 : -1;
}