diff --git a/Resources/Config/missiontext.plist b/Resources/Config/missiontext.plist
index f996d13f..2ea0dd6a 100644
--- a/Resources/Config/missiontext.plist
+++ b/Resources/Config/missiontext.plist
@@ -59,16 +59,6 @@
No, sorry.
-
- trumble_offer
- Commander [commander_name],\n\nYou look like someone who could use a Trumble on your [commander_shipname]!\n\nThis is yours for only 30 credits.
- trumble_offer_yesno
-
- NO
- No thanks. No pets on my ship.
- YES
- Okay, I'll take one, it looks cute.
-
oolite_trumble_offer_yesno
@@ -78,5 +68,16 @@
Okay, I'll take one, it looks cute.
+
+
+ trumble_offer
+ Commander [commander_name],\n\nYou look like someone who could use a Trumble on your [commander_shipname]!\n\nThis is yours for only 30 credits.
+ trumble_offer_yesno
+
+ NO
+ No thanks. No pets on my ship.
+ YES
+ Okay, I'll take one, it looks cute.
+
diff --git a/Resources/Scripts/oolite-legacy-script.plist b/Resources/Scripts/oolite-legacy-script.plist
index 87d4c5c2..9cb94f96 100644
--- a/Resources/Scripts/oolite-legacy-script.plist
+++ b/Resources/Scripts/oolite-legacy-script.plist
@@ -342,4 +342,4 @@
);
}
);
-}
\ No newline at end of file
+}
diff --git a/Resources/Scripts/oolite-trumbles.js b/Resources/Scripts/oolite-trumbles.js
new file mode 100644
index 00000000..2597e804
--- /dev/null
+++ b/Resources/Scripts/oolite-trumbles.js
@@ -0,0 +1,151 @@
+/*
+
+oolite-trumbles.js
+
+Script for random offers of trumbles.
+
+Oolite
+Copyright © 2007 Giles C Williams and contributors
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+MA 02110-1301, USA.
+
+*/
+
+
+this.name = "oolite-trumbles";
+this.author = "Jens Ayton";
+this.copyright = "© 2007 the Oolite team.";
+this.description = "Random offers of trumbles.";
+this.version = "1.69.2";
+
+
+this.log = function(message)
+{
+ // Uncomment next line for diagnostics.
+// LogWithClass("js.trumbles", message);
+}
+
+
+this.startUp = this.reset = function()
+{
+ /* For simplicity, ensure that missionVariables.trumbles is never
+ undefined when running the rest of the script. If it could be
+ undefined, it would be necessary to test for undefinedness before
+ doing any tests on the value, like so:
+ if (missionVariables.trumbles && missionVariables.trumbles == "FOO")
+ */
+ if (!missionVariables.trumbles)
+ {
+ missionVariables.trumbles = "";
+ this.log("missionVariables.trumbles was undefined, set it to empty string.");
+ }
+ else
+ {
+ this.log("Reset with missionVariables.trumbles = " + missionVariables.trumbles);
+ }
+}
+
+
+this.didDock = function()
+{
+ /* In the pre-JavaScript implementation, the mission variable was set to
+ OFFER_MADE while the mission screen was shown. If the player lanched
+ in that state, the offer would never be made again -- unless some
+ other script used the mission choice keys "YES" or "NO". This
+ implementation uses unique choice keys and doesn't change the mission
+ variable, which should be more reliable in all cases.
+ */
+ if (missionVariables.trumbles == "OFFER_MADE") missionVariables.trumbles = "BUY_ME"
+
+ if (player.dockedStation.isMainStation &&
+ missionVariables.trumbles == "" &&
+ !missionVariables.novacount && // Hmm. Why is this here? (Ported from legacy script)
+ player.credits > 6553.5)
+ {
+ this.log("Time to start selling trumbles.")
+ missionVariables.trumbles = "BUY_ME"
+ }
+
+ if (missionVariables.trumbles == "BUY_ME")
+ {
+ this.log("Trumbles are on the market.")
+ // 20% chance of trumble being offered, if no other script got this dock session first.
+ if (guiScreen == "GUI_SCREEN_STATUS"
+ && Math.random() < 0.2)
+ {
+ this.log("Offering trumble.")
+
+ let message =
+ "Commander " + player.name + ",\n\n" +
+ "You look like someone who could use a Trumble on your " + player.shipDescription + "!\n\n" +
+ "This is yours for only 30 credits."
+
+ // Show a mission screen.
+ mission.clearMissionScreen()
+ mission.setBackgroundImage("trumblebox.png")
+ mission.showMissionScreen()
+ mission.addMessageText(message)
+ mission.setChoicesKey("oolite_trumble_offer_yesno")
+ }
+ else
+ {
+ this.log("Not offering trumble. GUI screen is " + guiScreen)
+ }
+ }
+ else
+ {
+ this.log("Not offering trumble. mission_trumbles is " + missionVariables.trumbles)
+ }
+}
+
+
+this.missionScreenEnded = function()
+{
+ if (missionVariables.trumbles == "BUY_ME")
+ {
+ this.log("Trumble mission screen closed.")
+
+ if (mission.choice == "OOLITE_TRUMBLE_YES")
+ {
+ this.log("Trumble bought.")
+ mission.clearMissionScreen()
+ missionVariables.trumbles = "TRUMBLE_BOUGHT"
+ player.credits -= 30
+ player.awardEquipment("EQ_TRUMBLE")
+ }
+ else if (mission.choice == "OOLITE_TRUMBLE_NO")
+ {
+ this.log("Trumble rejected.")
+ mission.clearMissionScreen()
+ missionVariables.trumbles = "NOT_NOW"
+ }
+ }
+ else
+ {
+ this.log("Non-trumble mission screen closed.")
+ }
+}
+
+
+this.willExitWitchSpace = function()
+{
+ // If player has rejected a trumble offer, reset trumble mission with 2% probability per jump.
+ if (missionVariables.trumbles == "NOT_NOW" && Math.random < 0.02)
+ {
+ this.log("Resetting trumble buyability.")
+ missionVariables.trumbles = "BUY_ME"
+ }
+}
diff --git a/src/Core/Octree.m b/src/Core/Octree.m
index 7fa33fa4..ce6b2046 100644
--- a/src/Core/Octree.m
+++ b/src/Core/Octree.m
@@ -417,8 +417,7 @@ BOOL isHitByLine(int* octbuffer, unsigned char* collbuffer, int level, GLfloat r
OctreeDebugLogVerbose(@"----> testing octants...");
-// int nextlevel = octbuffer[level]; // previous absolute reference
- int nextlevel = level + octbuffer[level]; // now a relative reference
+ int nextlevel = level + octbuffer[level];
GLfloat rd2 = 0.5 * rad;
@@ -435,7 +434,6 @@ BOOL isHitByLine(int* octbuffer, unsigned char* collbuffer, int level, GLfloat r
if (octbuffer[nextlevel + oct0])
{
moveLine = offsetForOctant( oct0, rad);
-// moveLine = make_vector(rd2 - ((oct0 >> 2) & 1) * rad, rd2 - ((oct0 >> 1) & 1) * rad, rd2 - (oct0 & 1) * rad);
if (isHitByLine(octbuffer, collbuffer, nextlevel + oct0, rd2, u0, u1, moveLine, faces)) return YES; // first octant
}
@@ -446,19 +444,16 @@ BOOL isHitByLine(int* octbuffer, unsigned char* collbuffer, int level, GLfloat r
if (octbuffer[nextlevel + oct1])
{
moveLine = offsetForOctant( oct1, rad);
-// moveLine = make_vector(rd2 - ((oct1 >> 2) & 1) * rad, rd2 - ((oct1 >> 1) & 1) * rad, rd2 - (oct2 & 1) * rad);
if (isHitByLine(octbuffer, collbuffer, nextlevel + oct1, rd2, u0, u1, moveLine, 0)) return YES; // second octant
}
if (octbuffer[nextlevel + oct2])
{
moveLine = offsetForOctant( oct2, rad);
-// moveLine = make_vector(rd2 - ((oct2 >> 2) & 1) * rad, rd2 - ((oct2 >> 1) & 1) * rad, rd2 - (oct2 & 1) * rad);
if (isHitByLine(octbuffer, collbuffer, nextlevel + oct2, rd2, u0, u1, moveLine, 0)) return YES; // third octant
}
if (octbuffer[nextlevel + oct3])
{
moveLine = offsetForOctant( oct3, rad);
-// moveLine = make_vector(rd2 - ((oct3 >> 2) & 1) * rad, rd2 - ((oct3 >> 1) & 1) * rad, rd2 - (oct3 & 1) * rad);
if (isHitByLine(octbuffer, collbuffer, nextlevel + oct3, rd2, u0, u1, moveLine, 0)) return YES; // fourth octant
}
@@ -471,19 +466,16 @@ BOOL isHitByLine(int* octbuffer, unsigned char* collbuffer, int level, GLfloat r
if (octbuffer[nextlevel + oct1])
{
moveLine = offsetForOctant( oct1, rad);
-// moveLine = make_vector(rd2 - ((oct1 >> 2) & 1) * rad, rd2 - ((oct1 >> 1) & 1) * rad, rd2 - (oct1 & 1) * rad);
if (isHitByLine(octbuffer, collbuffer, nextlevel + oct1, rd2, u0, u1, moveLine, 0)) return YES; // fifth octant
}
if (octbuffer[nextlevel + oct2])
{
moveLine = offsetForOctant( oct2, rad);
-// moveLine = make_vector(rd2 - ((oct2 >> 2) & 1) * rad, rd2 - ((oct2 >> 1) & 1) * rad, rd2 - (oct2 & 1) * rad);
if (isHitByLine(octbuffer, collbuffer, nextlevel + oct2, rd2, u0, u1, moveLine, 0)) return YES; // sixth octant
}
if (octbuffer[nextlevel + oct3])
{
moveLine = offsetForOctant( oct3, rad);
-// moveLine = make_vector(rd2 - ((oct3 >> 2) & 1) * rad, rd2 - ((oct3 >> 1) & 1) * rad, rd2 - (oct3 & 1) * rad);
if (isHitByLine(octbuffer, collbuffer, nextlevel + oct3, rd2, u0, u1, moveLine, 0)) return YES; // seventh octant
}
@@ -493,7 +485,6 @@ BOOL isHitByLine(int* octbuffer, unsigned char* collbuffer, int level, GLfloat r
if (octbuffer[nextlevel + oct0])
{
moveLine = offsetForOctant( oct0, rad);
-// moveLine = make_vector(rd2 - ((oct0 >> 2) & 1) * rad, rd2 - ((oct0 >> 1) & 1) * rad, rd2 - (oct0 & 1) * rad);
if (isHitByLine(octbuffer, collbuffer, nextlevel + oct0, rd2, u0, u1, moveLine, 0)) return YES; // last octant
}
@@ -505,7 +496,7 @@ BOOL isHitByLine(int* octbuffer, unsigned char* collbuffer, int level, GLfloat r
int i;
for (i = 0; i< leafs; i++) octree_collision[i] = (char)0;
hasCollided = NO;
- //
+
if (isHitByLine(octree, octree_collision, 0, radius, v0, v1, kZeroVector, 0))
{
OctreeDebugLogVerbose(@"DEBUG Hit at distance %.2f", hit_dist);
@@ -585,7 +576,7 @@ BOOL isHitByOctree( Octree_details axialDetails,
// YES so octrees collide
axialCollisionBuffer[0] = (unsigned char)255; // mark
otherCollisionBuffer[0] = (unsigned char)255; // mark
- //
+
OctreeDebugLog(@"DEBUG Octrees collide!");
return YES;
}
@@ -593,12 +584,12 @@ BOOL isHitByOctree( Octree_details axialDetails,
// and each of its octants tested against the axial octree
// if any of them collides with this octant
// then we have a solid collision
- //
+
OctreeDebugLogVerbose(@"----> testing other octants...");
- //
+
// work out the nearest octant to the axial octree
int nearest_oct = ((otherPosition.x > 0.0)? 0:4)|((otherPosition.y > 0.0)? 0:2)|((otherPosition.z > 0.0)? 0:1);
- //
+
int nextLevel = otherBuffer[0];
int* nextBuffer = &otherBuffer[nextLevel];
unsigned char* nextCollisionBuffer = &otherCollisionBuffer[nextLevel];
@@ -612,7 +603,7 @@ BOOL isHitByOctree( Octree_details axialDetails,
{
nextDetails.octree = &nextBuffer[oct];
nextDetails.octree_collision = &nextCollisionBuffer[oct];
- //
+
voff = resolveVectorInIJK( offsetForOctant( oct, otherRadius), other_ijk);
nextPosition.x = otherPosition.x - voff.x;
nextPosition.y = otherPosition.y - voff.y;
@@ -621,7 +612,7 @@ BOOL isHitByOctree( Octree_details axialDetails,
return YES;
}
}
- //
+
// otherwise
return NO;
}
@@ -629,12 +620,12 @@ BOOL isHitByOctree( Octree_details axialDetails,
// we must test each of our octants against
// the other octree, if any of them collide
// we have a solid collision
- //
+
OctreeDebugLogVerbose(@"----> testing axial octants...");
- //
+
// work out the nearest octant to the other octree
int nearest_oct = ((otherPosition.x > 0.0)? 4:0)|((otherPosition.y > 0.0)? 2:0)|((otherPosition.z > 0.0)? 1:0);
- //
+
int nextLevel = axialBuffer[0];
int* nextBuffer = &axialBuffer[nextLevel];
unsigned char* nextCollisionBuffer = &axialCollisionBuffer[nextLevel];
@@ -648,7 +639,7 @@ BOOL isHitByOctree( Octree_details axialDetails,
{
nextDetails.octree = &nextBuffer[oct];
nextDetails.octree_collision = &nextCollisionBuffer[oct];
- //
+
voff = offsetForOctant(oct, axialRadius);
nextPosition.x = otherPosition.x + voff.x;
nextPosition.y = otherPosition.y + voff.y;
@@ -664,10 +655,10 @@ BOOL isHitByOctree( Octree_details axialDetails,
- (BOOL) isHitByOctree:(Octree*) other withOrigin: (Vector) v0 andIJK: (Triangle) ijk
{
BOOL hit = isHitByOctree( [self octreeDetails], [other octreeDetails], v0, ijk);
- //
+
hasCollision = hasCollision | hit;
[other setHasCollision: [other hasCollision] | hit];
- //
+
return hit;
}
@@ -680,10 +671,10 @@ BOOL isHitByOctree( Octree_details axialDetails,
details2.radius *= s2;
BOOL hit = isHitByOctree( details1, details2, v0, ijk);
- //
+
hasCollision = hasCollision | hit;
[other setHasCollision: [other hasCollision] | hit];
- //
+
return hit;
}