1 - Choose a name for you mod, for example "MyMod":
Load your mod in an ACS script:
Code: Select all
#library "MyScript"
#import "DynaItemSystem.acs"
#include "zcommon.acs"
script "myInitScript" ENTER {
if (!isInitialized()) {
loadMod("MyMod", 10);
}
}
loadMod(modName, priority) will load your mod with the given priority (from 1 to 32).
Mods with a higher priority have their items spawned first (Doom has a fixed priority of 0).
2 - Replace an existing item, with DECORATE:
Create an actor that must extend DynamicItem (or DynamicWeapon / DynamicPowerup).
Give the item effects in the DynamicPickup state, but do NOT use the Pickup state.
Example (taken from brutal doom) - a Minigun to replace the doom regular chaingun:
Code: Select all
ACTOR EmptyMini_Gun : WeaponGiver {
Weapon.AmmoGive1 0
DropItem "Mini_Gun"
}
ACTOR MyModChaingun : DoomChaingun {
Inventory.PickupSound "CBOXPKUP"
Inventory.PickupMessage "Minigun"
States {
DynamicPickup:
TNT1 A 0 A_GiveInventory("EmptyMini_Gun", 1)
TNT1 A 0 A_Jump(256, "GiveAmmo")
GiveAmmo:
TNT1 A 0 ACS_NamedExecuteWithResult("giveClipAmmo", 30.0 * 65536)
Stop
}
}
After running in ACS loadMod("MyMod", 10), the system makes this item spawn automatically.
Do NOT use the replace keyword: the system uses the name of the actor to replace stuff.
"MyMod" is the mod prefix, and "Chaingun" is the item being replaced.
If no actor with the mod prefix is found, the system spawns the regular doom chaingun.
In the DynamicPickup state, use the following script names to give stuff:
Code: Select all
ACS_NamedExecuteWithResult("giveClipAmmo", int amount)
ACS_NamedExecuteWithResult("giveShellAmmo", int amount)
ACS_NamedExecuteWithResult("giveRocketAmmo", int amount)
ACS_NamedExecuteWithResult("giveCellAmmo", int amount)
ACS_NamedExecuteWithResult("giveBackpack")
ACS_NamedExecuteWithResult("giveInvulnerabilitySphere", int tics)
ACS_NamedExecuteWithResult("giveBlurSphere", int tics)
ACS_NamedExecuteWithResult("giveRadSuit", int tics)
ACS_NamedExecuteWithResult("giveInfrared", int tics)
ACS_NamedExecuteWithResult("giveAllMap")
ACS_NamedExecuteWithResult("giveHealth", int amount, int limit)
ACS_NamedExecuteWithResult("giveArmor", int amount, int limit)
All amounts are decimal, so to give 30 something, you must write 30.0 * 65536
All tics are integers, and 35 tics = 1 second, so to give 30 seconds, you must write 30 * 35
All limits are integers, so to give a Soulsphere you must write ("giveHealth", 100.0 * 65536, 200)
3 - Create a drop item that gives half ammo / any other reward:
To define an item drop that can be dropped by monsters and only give half the rewards, use:
Code: Select all
ACTOR MyModChaingunDrop : MyModChaingun {
States {
GiveAmmo:
TNT1 A 0 ACS_NamedExecuteWithResult("giveClipAmmo", 15.0 * 65536)
Stop
}
}
The system will auto-detect the drops, and use the "Drop" suffix in the actor name to spawn the right item.
This is optional; if no actor with the "Drop" suffix is found, the system spawns the regular item.
4 - Create a new item, with DECORATE:
First, define the item with the correct name like in step 2.
Then, create a DynamicItemSpawner, for the system to recognize the new item:
Code: Select all
ACTOR DynamicRifleSpawner : DynamicItemSpawner replaces Rifle {}
Again, the name of the actor is important: always prefix with "Dynamic", and suffix with "Spawner".
What's left in the middle? "Rifle" - the name that the spawner will use to find items by mod.
In this case, the spawner will spawn a "MyModRifle", or "MyModRifleDrop" if a zombieman dropped the item.
5 - Create a new backpack, with DECORATE:
Example: the definition of the regular doom backpack:
Code: Select all
ACTOR DoomBackpack : DynamicItem {
Game Doom
SpawnID 144
Height 26
Inventory.PickupMessage "$GOTBACKPACK"
States {
DynamicSpawn:
BPAK A -1
Stop
DynamicPickup:
TNT1 A 0 A_JumpIf(CallACS("giveBackpack"), "DoubleAmmoCapacity")
TNT1 A 0 A_Jump(256, "GiveAmmo")
DoubleAmmoCapacity:
TNT1 A 0 ACS_NamedExecuteWithResult("doubleClipAmmoCapacity")
TNT1 A 0 ACS_NamedExecuteWithResult("doubleShellAmmoCapacity")
TNT1 A 0 ACS_NamedExecuteWithResult("doubleRocketAmmoCapacity")
TNT1 A 0 ACS_NamedExecuteWithResult("doubleCellAmmoCapacity")
TNT1 A 0 A_Jump(256, "GiveAmmo")
GiveAmmo:
TNT1 A 0 ACS_NamedExecuteWithResult("giveClipAmmo", 10.0 * 65536)
TNT1 A 0 ACS_NamedExecuteWithResult("giveShellAmmo", 4.0 * 65536)
TNT1 A 0 ACS_NamedExecuteWithResult("giveRocketAmmo", 1.0 * 65536)
TNT1 A 0 ACS_NamedExecuteWithResult("giveCellAmmo", 20.0 * 65536)
Stop
}
}
CallACS("giveBackpack") only returns true on the first backpack being given.
In that case, it doubles the ammo capacity and gives ammo. Otherwise, it just gives ammo.
6 - Create a new ammo type, with ACS:
All you have to create is a 1-line ACS script with the right ammo name, and then call that script from DECORATE.
Here are a few examples from brutal doom SE:
Code: Select all
#import "DynaAmmo.acs"
script "giveNewClipAmmo" (int amount) {
giveDynamicAmmo("NewClip", amount);
}
You might also need this for the backpack:
Code: Select all
script "doubleNewClipAmmoCapacity" (int amount) {
doubleAmmoCapacity("NewClip");
}
7 - Configure a different armor absorb ratio, with ACS:
By default, the Dynamic Armor System uses a 50% absorb at 200 armor (default from doom).
To configure a different absorb value for a mod, follow this example (from brutal doom):
Code: Select all
#library "MyScript"
#import "DynaItemSystem.acs"
#import "DynaArmorSystem.acs"
#include "zcommon.acs"
script "myInitScript" ENTER {
if (!isInitialized()) {
loadMod("MyMod", 10);
configLargeArmorAbsorb(70.0);
configLargeArmorAmount(200);
}
}
This means that, in brutal doom, at 200 armor, 70% damage will be absorbed.
The higher the configLargeArmorAbsorb, the more armor is effective.
The higher the configLargeArmorAmount, the less armor is effective.