Sure. If you're going to do this totally properly, you would need to edit the config.exe to provide a new keybinding (so people can set your new action key to whatever they want). Writing proper controls where gamepads, joysticks, and keyboards all work the way you expect them to and can be bound to different values is a HUGE thing and I don't want to write up a whole tutorial on that. So I'll skip that and just assume you want to hardcode a new key. So let's say you want 'V' to be a button that creates a yeti. I dunno why you'd want to do that, but let's just say you did

First you go to the scrInit script and add a new global. You'll see all these global.key**** values. Add a new one, something like
global.keyYetiVal = ord('V');
There's some gamepad code underneath that, and there's more code under that for importing key values from the config files. But like I said, I'm not covering that.
Next you'll see there's a bunch of scripts under the "Control" directory, stuff like checkAttack, checkAttackPressed, checkAttackReleased. Copy those three but rename them checkYeti, checkYetiPressed, checkYetiReleased. Then in each one of those you modify them to look like this, by commenting out the first three lines and replacing the attack global with your new yeti global:
//if (gamepad.attack)
// return gamepad.attack;
//else
return (keyboard_check(global.keyYetiVal));
Again, if we were doing gamepad stuff this would break everything, but leaving it in without doing proper gamepad code will screw things up.
Actions are handled in the oPlayer1 Step event, in the second block of code. What you put here really depends on how you want your button to behave. But let's assume our Yeti spawning behaves like attacking does: you can't do it when you're ducking or transitioning from a hang, or if you're already attacking, or exiting a level. So we'll insert our code where I indicate below, at line 805:
if (kAttackPressed and state != DUCKING and state != DUCKTOHANG and not whipping and
sprite_index != sPExit and sprite_index != sDamselExit)
{
image_speed = 0.6;
if (global.isTunnelMan)
{
if (platformCharacterIs(ON_GROUND))
{
sprite_index = sTunnelAttackL;
image_index = 0;
whipping = true;
}
}
else if (global.isDamsel)
{
sprite_index = sDamselAttackL;
image_index = 0;
whipping = true;
}
else
{
sprite_index = sAttackLeft;
image_index = 0;
whipping = true;
}
}
// BEGIN NEW CODE
else if (checkYetiPressed() and state != DUCKING and state != DUCKTOHANG and not whipping and
sprite_index != sPExit and sprite_index != sDamselExit)
{
//// YOUR STUFF HERE
}
// END NEW CODE
else if (kAttackPressed and kDown)
{
// pick up item
if (collision_rectangle(x-8, y, x+8, y+8, oItem, 0, 0))
{
...
So, yeah. That's the quick and dirty way, but again, it'll take a lot more work to make the keys rebindable and working on all sorts of controllers. I may write a tutorial about that some day. But it's boring. You know what is NOT boring? A video of my yeti-launching Spelunky mod
http://www.youtube.com/watch?v=rPOXbLp73oM