Here is how it works: you define a powerup that inherits from PowerScriptedEffect. The script then takes place in four base states:
ScriptInit:
Similarly to the Pickup: or Use: states of a CustomInventory, the calls from a ScriptInit: are executed in just one tic. This can be used to set up things that the PowerUp does from the start.
ScriptReInit:
Same as above, but this state is instead executed if you pick up another scripted powerup of the same type.
ScriptExit:
The same thing as ScriptInit, but on the other end of the chain: those are executed when the powerup expires or is otherwise removed.
Script:
The meat and bone of this new type of Powerup. While the powerup is in a player's inventory, it will iterate through its states at the normal speed (be sure to make this state last at least one tic!). Very powerful effects are possible: you can use the various A_Checks and A_Jumps, you can A_Give/TakeInventory, you can A_SpawnWhatever things, you can A_Set and A_Unset, and so on.
With this, you can do a lot of types of powerups. They can be pretty simple, or quite elaborate.
Here is a pretty simple example. This powerup generates rockets. You'll get a total of 12 rockets: one every five seconds for one minute.
Code: Select all
Actor PowerRocketGenerator : PowerScriptedEffect
{
Powerup.Duration -60
States
{
Script:
// 35 * 5 = 175, so one rocket every 5 seconds
TNT1 A 175 A_GiveInventory("RocketAmmo")
Loop
}
}
Actor RocketGenerator : PowerupGiver
{
+INVENTORY.ALWAYSPICKUP
+INVENTORY.AUTOACTIVATE
Inventory.MaxAmount 0
Inventory.PickupMessage "Picked-up a portable rocket generator"
Powerup.Type "RocketGenerator"
States
{
Spawn:
BPAK A -1
Stop
}
}
Now here is a more complicated powerup. You can see how it uses many custom states, several inventory tokens, and a lot of A_Jump* checks to achieve its effects.
These combat stims will make you fast and strong, and give you a healing factor. You'll even regenerate above 100% health! However, if you're hurt, your metabolism will no longer sustain some of these effects. If your health goes below 90, you lose the "rage rune" effect. If it falls below 80, you will no longer regenerate above 100. If it falls below 50, you will lose the berserk effect. And if it falls below 25, you will lose all of these boosts entirely, but instead you get speed so that you can run away very quickly! After 30 seconds, the speed boost goes away too. If during your flight you pickup another of these powerups, the stims are back in full force but you lose the speed boost.
Code: Select all
// Special effects
Actor PowerBerserkFiringSpeed : PowerDoubleFiringSpeed { Powerup.Duration 0x7FFFFFFF }
Actor PowerBerserkSpeed : PowerSpeed { Powerup.Duration 0x7FFFFFFF }
Actor BerserkDepletionToken : Inventory {}
Actor BerserkResetToken : Inventory {}
Actor BerserkTicToken : Inventory { Inventory.MaxAmount 1050 }
// The Super Berserk!
Actor PowerSuperBerserk : PowerScriptedEffect
{
States
{
ScriptReInit:
TNT1 A 0 A_GiveInventory("BerserkResetToken")
// Fall through to ScriptInit
ScriptInit:
TNT1 A 0 A_TakeInventory("BerserkDepletionToken", 255)
TNT1 A 0 A_GiveInventory("PowerStrength")
TNT1 A 0 A_GiveInventory("PowerBerserkFiringSpeed")
TNT1 A 0 HealThing(100, 0)
TNT1 A 0 A_SelectWeapon("Fist")
Stop
ScriptReset:
TNT1 A 0 A_TakeInventory("BerserkResetToken", 255)
TNT1 A 0 A_TakeInventory("PowerBerserkSpeed", 255)
// Fall through to Script
Script:
TNT1 A 1 A_GiveInventory("BerserkTicToken")
TNT1 A 0 A_JumpIfHealthLower(25, "Yipe")
TNT1 A 0 A_JumpIfInventory("PowerStrength", 1, "StrengthHealthCheck")
TNT1 A 0 A_JumpIfHealthLower(80, "RegenTokenCheck")
TNT1 A 0 A_JumpIfInventory("PowerBerserkFiringSpeed", 1, "SpeedHealthCheck")
TNT1 A 0 A_JumpIfInventory("BerserkTicToken", 105, "RegenCheck")
Loop
RegenCheck:
TNT1 A 0 A_TakeInventory("BerserkTicToken", 1050)
TNT1 A 0 A_JumpIfHealthLower(100, "LesserRegen")
TNT1 A 0 A_JumpIfHealthLower(120, "GreaterRegen")
Goto Script
GreaterRegen:
TNT1 A 0 A_JumpIfInventory("BerserkDepletionToken", 1, "Script") // No regen for you!
TNT1 A 0 A_GiveInventory("HealthBonus") // Gain +1 health to a maximum of 120
Goto Script
LesserRegen:
TNT1 A 0 A_GiveInventory("HealthBonus") // Gain +1 health to a maximum of 100
Goto Script
SpeedHealthCheck:
TNT1 A 0 A_JumpIfHealthLower(90, "SpeedLoss")
Goto Script +5
SpeedLoss: // Sorry, you took too much damage to sustain your super attack speed!
TNT1 A 0 A_Print("Your attacks are no longer accelerated")
TNT1 A 0 A_TakeInventory("PowerBerserkFiringSpeed", 255)
Goto Script +5
RegenTokenCheck:
TNT1 A 0 A_JumpIfInventory("BerserkDepletionToken", 1, "RegenLoss")
Goto Script+4
RegenLoss: // Sorry, but you are hurt and can no longer regen above human limits
TNT1 A 0 A_Print("Your regen is weakened")
TNT1 A 0 A_GiveInventory("BerserkDepletionToken")
Goto Script+4
StrengthHealthCheck:
TNT1 A 0 A_JumpIfHealthLower(50, "StrengthLoss")
Goto Script +3
StrengthLoss: // Sorry, you took too much damage to sustain your super strength!
TNT1 A 0 A_Print("Your punches are no longer superhumanly strong")
TNT1 A 0 A_TakeInventory("PowerStrength", 255)
Goto Script +3
Yipe: // A last adrenalin surge that helps running away very quickly!
TNT1 A 0 A_Print("Run away!")
TNT1 A 0 A_GiveInventory("PowerBerserkSpeed")
TNT1 A 0 A_TakeInventory("BerserkTicToken", 1050)
// fall through to YipeLoop
YipeLoop:
TNT1 A 1 A_GiveInventory("BerserkTicToken")
TNT1 A 0 A_JumpIfInventory("BerserkResetToken", 1, "ScriptReset")
TNT1 A 0 A_JumpIfInventory("BerserkTicToken", 1050, "YipeEnd")
Loop
YipeEnd:
TNT1 A 0 A_Print("Adrenalin fading out!")
Stop // This removes the powerup
ScriptExit: // Cleanup!
TNT1 A 0 A_TakeInventory("BerserkTicToken", 1050)
TNT1 A 0 A_TakeInventory("PowerBerserkFiringSpeed", 255)
TNT1 A 0 A_TakeInventory("BerserkDepletionToken", 255)
TNT1 A 0 A_TakeInventory("BerserkResetToken", 255)
TNT1 A 0 A_TakeInventory("PowerBerserkSpeed", 255)
TNT1 A 0 A_TakeInventory("PowerStrength", 255)
Stop
}
}
Actor SuperBerserk : PowerupGiver replaces Berserk
{
Game Doom
SpawnID 134
+COUNTITEM
+INVENTORY.ALWAYSPICKUP
+INVENTORY.AUTOACTIVATE
Inventory.MaxAmount 0
Inventory.PickupMessage "Combat stims!"
Inventory.PickupSound "misc/p_pkup"
Powerup.Type "SuperBerserk"
States
{
Spawn:
PSTR A -1
Stop
}
}
Now, try those, use them and abuse them to see if you can get them to break. I'd like to be sure they work flawlessly when I'll move them to Code Submission. Oh, and as always, a patch is included in the zip.