I was reading in another thread about the oBasketball object that Derek implemented for Spelunky but never added. I decided to check it out for myself. Here's how I did it (it's like a three-minute hack). If you just want to grab the final basketball mod,
go here!
First I wanted to test out the basketball to see what it's like. So I decided to make it so that whenever you break open a jar, you'll get a basketball. (I didn't choose crates because those don't spawn often enough.)
In GameMaker, open up the oJar object. It's under the Objects-->Items directory, or go to Edit-->Find Resource and type "oJar".
We want to affect its behavior when it's broken apart, so we open the Destroy event and open the script in there. You'll see this chunk of code:
if (rand(1,3) == 1) instance_create(x, y, oGoldChunk);
else if (rand(1,6) == 1) instance_create(x, y, oGoldNugget);
else if (rand(1,12) == 1) instance_create(x, y, oEmeraldBig);
else if (rand(1,12) == 1) instance_create(x, y, oSapphireBig);
else if (rand(1,12) == 1) instance_create(x, y, oRubyBig);
else if (rand(1,6) == 1) instance_create(x-8, y-8, oSpider);
else if (rand(1,12) == 1)
{
if (colLeft) instance_create(x, y-8, oSnake);
else if (colRight) instance_create(x-16, y-8, oSnake);
else instance_create(x-8, y-8, oSnake);
}
This code is what determines how often things come out of jars: a 1 in 3 chance of a gold chunk, otherwise a 1 in 6 chance of a nugget, and then different possibilities until you get all the way to spider or snake. What we can do is simply change the first line so it's always true and always generates a basketball.
if (rand(1,1) == 1) instance_create(x, y, oBasketball);
else if (rand(1,6) == 1) instance_create(x, y, oGoldNugget);
else if (rand(1,12) == 1) instance_create(x, y, oEmeraldBig);
else if (rand(1,12) == 1) instance_create(x, y, oSapphireBig);
else if (rand(1,12) == 1) instance_create(x, y, oRubyBig);
else if (rand(1,6) == 1) instance_create(x-8, y-8, oSpider);
else if (rand(1,12) == 1)
{
if (colLeft) instance_create(x, y-8, oSnake);
else if (colRight) instance_create(x-16, y-8, oSnake);
else instance_create(x-8, y-8, oSnake);
}
What that does is it generates a random integer between 1 and 1, which will of course always equal 1 and spawn a basketball.
Now, this is nice for trying out the basketball, but you might want to mess around with the code to make it spawn like anything else. And probably from a crate. The code for crate spawning is actually inside the oPlayer1 object, so if you open that up and go to the Step event, you want to open the second Action block of code and go down to line 214, where there's this code:
// open crate
if (kUp and kAttackPressed and collision_point(x, y, oCrate, 0, 0))
{
if (isRealLevel()) global.totalCrates += 1;
chest = instance_place(x, y, oCrate);
if (isRoom("rTutorial")) obj = instance_create(chest.x, chest.y, oBombBag);
else if (rand(1,500) == 1) obj = instance_create(chest.x, chest.y, oJetpack);
else if (rand(1,200) == 1) obj = instance_create(chest.x, chest.y, oCapePickup);
else if (rand(1,100) == 1) obj = instance_create(chest.x, chest.y, oShotgun);
else if (rand(1,100) == 1) obj = instance_create(chest.x, chest.y, oMattock);
else if (rand(1,100) == 1) obj = instance_create(chest.x, chest.y, oTeleporter);
else if (rand(1,90) == 1) obj = instance_create(chest.x, chest.y, oGloves);
else if (rand(1,90) == 1) obj = instance_create(chest.x, chest.y, oSpectacles);
else if (rand(1,80) == 1) obj = instance_create(chest.x, chest.y, oWebCannon);
else if (rand(1,80) == 1) obj = instance_create(chest.x, chest.y, oPistol);
else if (rand(1,80) == 1) obj = instance_create(chest.x, chest.y, oMitt);
else if (rand(1,60) == 1) obj = instance_create(chest.x, chest.y, oPaste);
else if (rand(1,60) == 1) obj = instance_create(chest.x, chest.y, oSpringShoes);
else if (rand(1,60) == 1) obj = instance_create(chest.x, chest.y, oSpikeShoes);
else if (rand(1,60) == 1) obj = instance_create(chest.x, chest.y, oMachete);
else if (rand(1,40) == 1) obj = instance_create(chest.x, chest.y, oBombBox);
else if (rand(1,40) == 1) obj = instance_create(chest.x, chest.y, oBow);
else if (rand(1,20) == 1) obj = instance_create(chest.x, chest.y, oCompass);
else if (rand(1,10) == 1) obj = instance_create(chest.x, chest.y, oParaPickup);
else if (rand(1,2) == 1) obj = instance_create(chest.x, chest.y, oRopePile);
else obj = instance_create(chest.x, chest.y, oBombBag);
obj.cost = 0;
playSound(global.sndPickup);
if (chest == holdItem)
{
holdItem = 0;
pickupItemType = "";
}
with chest { instance_create(x, y, oPoof); instance_destroy(); }
kAttackPressed = false;
}
If you'd like the basketball to spawn about as often as, say, the parachute, just put insert the following line between oParaPickup and oRopePile:
else if (rand(1,10) == 1) obj = instance_create(chest.x, chest.y, oParaPickup);
// NEW LINE HERE
else if (rand(1,10) == 1) obj = instance_create(chest.x, chest.y, oBasketball);
else if (rand(1,2) == 1) obj = instance_create(chest.x, chest.y, oRopePile);
I decided to release this as a mod, because hey, why not!
http://tinysubversions.com/spelunkybball/