Chaosforge Forum

  • December 21, 2024, 07:17
  • Welcome, Guest
Please login or register.



Login with username, password and session length
Pages: [1] 2 3 4  All

Author Topic: Changing the ammo system?  (Read 33556 times)

Autoquark

  • Backer
  • Lance Corporal
  • *
  • *
  • Offline Offline
  • Posts: 23
  • Lost Soul
    • View Profile
Changing the ammo system?
« on: March 28, 2013, 03:51 »

This is my first real attempt at modding doomRL, so please bear with me if these questions are rather basic.

I'm trying to alter the doomRL ammo system to be like the system in Doom, where the player has a fixed capacity for each kind of ammo. I thought the easiest way to do this might be to change the size that ammo stacks to in the inventory to the amount I want the player to be able to hold, and then only allow the player's inventory to hold one ammo stack of each kind. Would it be possible to do this using the OnPickup hook? If so, should I define my own ammo types and add the hook to them, or just use the general OnPickup hook and the existing ammo types?

Thanks for any help.
Logged

tehtmi

  • Programmer
  • Local Inquisitor
  • Lieutenant Colonel
  • *
  • *
  • Offline Offline
  • Posts: 458
    • View Profile
Re: Changing the ammo system?
« Reply #1 on: March 28, 2013, 04:58 »

Ammo is maybe the weirdest item type in DoomRL because it is the only thing that stacks.  Ammo stack items are created automatically by the engine to do ammo management, sometimes in unintuitive ways.  Because of this, it won't be easy to implement this kind of system robustly, but here are some approaches you could try.

Hooks on ammo items don't work well in the current version.  OnPickupCheck doesn't seem to be called at all, and OnPickup is called after the ammo is added.  This could probably still be used, but you would have to fix up the ammo in the player's inventory after the fact.  Another thing you can do is use powerups to add ammo to the player's inventory like Game Hunter does in HereticRL.  OnPickupCheck and OnPickup work for powerups and could be used to implement any logic you like.  Either way, you have to worry about other ways that ammo can be created like dropping ammo from the inventory and unloading weapons.  These will probably be hard to handle well.

Yet another approach would be not to use items for ammo at all.  You could add custom properties to the player (or wherever) to track ammo, and again use powerups to add ammo to these counters.  If you go this approach, all your weapons would need to have custom OnFire and OnReload hooks to make use of the custom ammo system, but it is probably doable.  The difficulty I would anticipate here is displaying the ammo to the player.  Probably I would try to add it in to the name of currently equipped weapons using some combination of OnEquip, OnRemove, and OnEquipTick.
Logged

Autoquark

  • Backer
  • Lance Corporal
  • *
  • *
  • Offline Offline
  • Posts: 23
  • Lost Soul
    • View Profile
Re: Changing the ammo system?
« Reply #2 on: March 28, 2013, 08:27 »

Thanks for the detailed answer. I might leave that idea for a bit, at least until I'm more familiar with the system and lua. I guess I'll add some other random questions:

1. If I'm creating an episode, and I want to define custom items, where should I put the definitions? And which hook is best for adding stuff to the player's starting inventory?

EDIT: Nevermind, after looking at the skulltag arena files, I see that you have to use register_item. I thought that they had to be put inside a function.

2. I was also wondering about creating my own mod items. I guess you use ui.msg_choice to let the player choose an item slot to mod, but I can't find out from the wiki how to reference the player's equipped items. Is there any example code for this?

3. Is there any easy way to prevent the level generator from generating the built-in items, or will I have to wait for total conversion mod support?

Thanks again for helping.

EDIT2: After adding various missing values to my new item which weren't included in the tutorial template, I now get the following error message:

core\\core.lua:221: attempt to index field '?' (a nil value)

Here's my item declaration:

Code: [Select]
register_item "new_pulsecannon" {
name = "pulse cannon",
id = "extra_pulsecannon",
desc = "The Microsol Pulse Cannon provides cost-effective firepower thanks to the self-recharging battery.",
ascii = "}" ,
sprite = SPRITE_CHAINGUN,
level = 1,
weight = 1000, --bit of a guess, see item generation page on wiki
flags = {IF_RECHARGE},
firstmsg = "",
color_id = "generic",
--type specific
    type         = ITEMTYPE_RANGED, --required field
damage        = "2d4",           --required field
    damagetype    = DAMAGE_BULLET,   --required field
    group         = "weapon-pistol", --defaults to "weapon-other"
    fire          = 10,              --defaults to 10
    acc           = 0,               --defaults to 0
    radius        = 0,               --defaults to 0 (_RANGED and _NRANGED only)
    shots         = 1,               --defaults to 0
    ammo_id       = "ammo",        --required field (_RANGED only)
    ammomax       = 12,              --required field (_RANGED only)
    reload        = 12,              --defaults to 10 (_RANGED only)
    shotcost      = 1,               --defaults to 0 (_RANGED only). I think 1 makes it a rapid-fire weapon and 0 a single-shot
    altfire       = ALT_AIMED,       --defaults to ALT_NONE (_MELEE and _RANGED only)
    altfirename   = "aimed shot",    --default depends on altfire (_MELEE and _RANGED only)
    altreload     = RELOAD_FULL,     --defaults to RELOAD_NONE (_RANGED only)
    altreloadname = "full",          --default depends on altreload (_RANGED only)
    --soundID       = "pistol",        --defaults to "id" (_RANGED and _NRANGED only)
    missile       = "gun",
psprite   = SPRITE_PLAYER_CHAINGUN --the sprite used to represent the player when equipped
}
« Last Edit: March 28, 2013, 12:52 by Autoquark »
Logged

tehtmi

  • Programmer
  • Local Inquisitor
  • Lieutenant Colonel
  • *
  • *
  • Offline Offline
  • Posts: 458
    • View Profile
Re: Changing the ammo system?
« Reply #3 on: March 29, 2013, 02:22 »

2. I was also wondering about creating my own mod items. I guess you use ui.msg_choice to let the player choose an item slot to mod, but I can't find out from the wiki how to reference the player's equipped items. Is there any example code for this?

ui.msg_choice is actually what the real game uses, but there are more abstraction layers built up that you can use.  Mods are somewhat complicated, so here are the hooks from mod_power for you to base your stuff off of:
Code: [Select]
OnUseCheck = function(self,being)
local item, result = being:pick_mod_item('P',being.techbonus)
if not result then return false end
if item ~= nil then self:add_property("chosen_item", item) end
return true
end,

OnUse = function(self,being)
if not self:has_property("chosen_item") then return true end
local item = self.chosen_item
if item.itype == ITEMTYPE_MELEE then
item.damage_sides = item.damage_sides + 1
elseif item.itype == ITEMTYPE_RANGED then
if item.damage_sides >= item.damage_dice then
item.damage_sides = item.damage_sides + 1
else
item.damage_dice = item.damage_dice + 1
end
elseif item.itype == ITEMTYPE_ARMOR then
item.armor = item.armor + 2
elseif item.itype == ITEMTYPE_BOOTS then
item.armor = item.armor * 2
end
item:add_mod('P')
return true
end,
The whole dance with having to use OnUseCheck and the custom property is inelegant, but it allows the mod to not take any time when the player cancels it.  If you don't like that, here's the simpler version from before the change.
Code: [Select]
OnUse = function(self,being)
local item, result = being:pick_mod_item('P',being.techbonus)
if not item then return result end
if item.itype == ITEMTYPE_MELEE then
item.damage_sides = item.damage_sides + 1
elseif item.itype == ITEMTYPE_RANGED then
if item.damage_sides >= item.damage_dice then
item.damage_sides = item.damage_sides + 1
else
item.damage_dice = item.damage_dice + 1
end
elseif item.itype == ITEMTYPE_ARMOR then
item.armor = item.armor + 2
elseif item.itype == ITEMTYPE_BOOTS then
item.armor = item.armor * 2
end
item:add_mod('P')
return true
end,
Using :pick_mod_item will prompt the player, check for assemblies, and make sure you are allowed to mod the item with the given mod.

Quote
3. Is there any easy way to prevent the level generator from generating the built-in items, or will I have to wait for total conversion mod support?

For a particular item, you can just do e.g.
Code: [Select]
items.pistol.weight = 0
If you want to get rid of all of them, you can just loop through before registering any of your own items
Code: [Select]
for _, it in ipairs(items) do
  it.weight = 0
end
Modifying prototypes after they are declared is a bit messy, but it's the only option for built-in things.

Quote
Here's my item declaration:
Wow, what a useless error message.  It is failing because "gun" is not defined as a missile.  It has been renamed to "mgun".  (I think all the missiles gut "m" added at the beginning and all the shotgun-type missiles got "s" added to the beginning.)

Also, the id field should no longer be included in the table; the initial argument to register_item (e.g. "new_pulsecannon") will be used as the id.
Logged

SPTX

  • Sergeant
  • *
  • Offline Offline
  • Posts: 77
  • Lost Soul
    • View Profile
Re: Changing the ammo system?
« Reply #4 on: March 29, 2013, 11:45 »

It is failing because "gun" is not defined as a missile.  It has been renamed to "mgun".  (I think all the missiles gut "m" added at the beginning and all the shotgun-type missiles got "s" added to the beginning.)

Also, the id field should no longer be included in the table; the initial argument to register_item (e.g. "new_pulsecannon") will be used as the id.
I have the same error as this dude (and did the same mistake) however even after changing "gun" to "mgun" I still have the error.
Here is the incriminated code.
Code: [Select]
register_item "SPTXsniperrifle"{
name = "Long range rifle",
    type = ITEMTYPE_RANGED,
sprite = SPRITE_CHAINGUN,
level = 2,
weight = 160,
psprite = SPRITE_PLAYER_SHOTGUN,
    ammo_id = "ammo",
    group = "weapon-shotgun",
    damage = "10d2",
damagetype = DAMAGE_BULLET,
    missile = "mgun",
    fire = 15,
    reload = 10,
    acc = 2,
    ammomax = 5,
flags = {IF_PUMPACTION,IF_SHOTGUN},
    desc = "A rifle designed to shoot targets at very long distances.",
    altfire = ALT_AIMED,
}
Logged

tehtmi

  • Programmer
  • Local Inquisitor
  • Lieutenant Colonel
  • *
  • *
  • Offline Offline
  • Posts: 458
    • View Profile
Re: Changing the ammo system?
« Reply #5 on: March 29, 2013, 11:51 »

I have the same error as this dude (and did the same mistake) however even after changing "gun" to "mgun" I still have the error.

Since you have IF_SHOTGUN, the game is looking in the shotgun list instead of the normal list.  If you want it to be a shotgun, change the missile to a proper shotgun type (like "snormal"), otherwise remove the IF_SHOTGUN flag.
Logged

SPTX

  • Sergeant
  • *
  • Offline Offline
  • Posts: 77
  • Lost Soul
    • View Profile
Re: Changing the ammo system?
« Reply #6 on: March 29, 2013, 12:09 »

Since you have IF_SHOTGUN, the game is looking in the shotgun list instead of the normal list.  If you want it to be a shotgun, change the missile to a proper shotgun type (like "snormal"), otherwise remove the IF_SHOTGUN flag.
Well that fixed it. Thanks. A lot.
Logged

Autoquark

  • Backer
  • Lance Corporal
  • *
  • *
  • Offline Offline
  • Posts: 23
  • Lost Soul
    • View Profile
Re: Changing the ammo system?
« Reply #7 on: March 29, 2013, 14:37 »

Thanks. I've now got the mod running with my own weapons being generated and working correctly. Just a couple of questions: what's the property name of "fire" on a weapon? The wiki says "usetime", but I've tried both "usetime" and just "fire" and I get a lua error saying I'm reading an undeclared variable.
Also, how are OnAltFire hooks for scripted alt fire modes meant to be used. Should I temporarily alter the stats of the weapon and then change them back in the OnFired hook, or is that completely wrong?

I know the lua files for the main game aren't being released yet, but have you considered including an example file with each release containing the definitions for one or two items of each type, and perhaps the ai for one or two enemies? Having examples to look at would be a great help, and if they were copied from the game lua files, they would always be up to date, which would be helpful when there are changes to the system that the wiki hasn't caught up with.

EDIT: Another question - how do I access the player's inventory? I want to go through it to check if a particular kind of ammo is present - I'm trying to make a weapon that draws ammo directly from the inventory.
« Last Edit: March 29, 2013, 16:14 by Autoquark »
Logged

tehtmi

  • Programmer
  • Local Inquisitor
  • Lieutenant Colonel
  • *
  • *
  • Offline Offline
  • Posts: 458
    • View Profile
Re: Changing the ammo system?
« Reply #8 on: March 29, 2013, 21:14 »

...what's the property name of "fire" on a weapon? The wiki says "usetime", but I've tried both "usetime" and just "fire" and I get a lua error saying I'm reading an undeclared variable.
"fire" is the name of the prototype property and "usetime" is the object property.  If the Lua error is for an undeclared variable, the problem could be the context you are using it in, as that doesn't sound like an error you'd get when declaring an item.  I'd have to see what you're doing.

Quote
Also, how are OnAltFire hooks for scripted alt fire modes meant to be used. Should I temporarily alter the stats of the weapon and then change them back in the OnFired hook, or is that completely wrong?

OnAltFire is called when you use altfire = ALT_SCRIPT.  I don't consider this to be very mature yet, as most of DoomRL alternate fire modes are not implemented in Lua.  However, what you suggest sounds like the best way to do it to me.  DoomRL's rocket launcher actually uses OnFire to switch the stats back, but I think OnFired would generally work better.

Quote
I know the lua files for the main game aren't being released yet, but have you considered including an example file with each release containing the definitions for one or two items of each type, and perhaps the ai for one or two enemies? ...
This would probably be good, but I'd have to go through Kornel to get permission about what we can post.

Quote
how do I access the player's inventory? I want to go through it to check if a particular kind of ammo is present - I'm trying to make a weapon that draws ammo directly from the inventory.

Currently the only real access seems to be through the inventory iterator
Code: [Select]
for it in player.inv:items() do
  print(it.name)
end
The order they are stored in is undefined (i.e. should not be relied upon).  The rest of the inventory API would be .inv:empty() (this is a predicate), .inv:clear(), .inv:add(it, [params])
Logged

Autoquark

  • Backer
  • Lance Corporal
  • *
  • *
  • Offline Offline
  • Posts: 23
  • Lost Soul
    • View Profile
Re: Changing the ammo system?
« Reply #9 on: March 30, 2013, 10:02 »

I tried looking through the inventory like this:
Code: [Select]
OnFire = function(self) --to draw ammo from inventory
for it in player.inv:items() do
if it.id == "hl_nuclear_ammo" then
it.ammo = it.ammo - 1
return true
end
return false
end
end,
But the hook never seems to return true, although I'm sure I have an ammo item with that id in my inventory. If I make the function always return true, the weapon fires, so I think the problem must be here.

I've worked out what the problem with the "usetime" property was - it wasn't the property at all, I was using the floor() function to round the result of a calculation and I didn't realise I had to put "math.floor()". It works now. Thanks for all your help.
Logged

tehtmi

  • Programmer
  • Local Inquisitor
  • Lieutenant Colonel
  • *
  • *
  • Offline Offline
  • Posts: 458
    • View Profile
Re: Changing the ammo system?
« Reply #10 on: March 30, 2013, 10:10 »

I tried looking through the inventory like this:
The "return false" needs to be outside the loop for this to work as you intended.  You may also need to manually :destroy() the item when its ammo reaches 0, but I'm not 100% sure.
Logged

Autoquark

  • Backer
  • Lance Corporal
  • *
  • *
  • Offline Offline
  • Posts: 23
  • Lost Soul
    • View Profile
Re: Changing the ammo system?
« Reply #11 on: March 30, 2013, 16:56 »

Oops! Silly mistake. You were right about having to destroy the ammo item when it ran out, too. That works now, but I have some more questions:

1. I have a missile defined with the MF_RAY flag set, but the game seems to ignore that and still draws a bullet travelling across the screen. It works in console mode however - has the flag become deprecated since graphics were introduced?

2. Is there a list of sprites somewhere? I don't know the names of any of the missile sprites, so I've had to put in random sprites that I do know for now. Although I suppose there is something to be said for a shotgun that shoots shotguns...

3. I've been trying to change the missile property of a weapons using the OnFire hook, but I always get an error when I try to assign it - what should the assignment look like?

4. This is just out of interest, for now: I notice that calling Player:power_backpack() reshuffles the player's ammo stacks. Is there any way to do this without also turning the backpack on? It would be quite a handy feature.
Logged

tehtmi

  • Programmer
  • Local Inquisitor
  • Lieutenant Colonel
  • *
  • *
  • Offline Offline
  • Posts: 458
    • View Profile
Re: Changing the ammo system?
« Reply #12 on: March 30, 2013, 17:18 »

1. I have a missile defined with the MF_RAY flag set, but the game seems to ignore that and still draws a bullet travelling across the screen. It works in console mode however - has the flag become deprecated since graphics were introduced?
I wouldn't say it is deprecated, just not supported in graphics mode yet.

Quote
2. Is there a list of sprites somewhere? I don't know the names of any of the missile sprites, so I've had to put in random sprites that I do know for now. Although I suppose there is something to be said for a shotgun that shoots shotguns...

Here's all the sprite constants that are declared; use them.  (Spoilered for length)
Spoiler (click to show/hide)
Alternatively, you could also just copy the values from things you know like beings.imp.sprite.

Quote
3. I've been trying to change the missile property of a weapons using the OnFire hook, but I always get an error when I try to assign it - what should the assignment look like?
The value needs to be the number id of the missile.  Number ids are subject to change between versions, so you should translate from the string id e.g.
Code: [Select]
  it.missile = missiles.mgun.nid
  -- or
  it.missile = missiles[string_id].nid

Quote
4. This is just out of interest, for now: I notice that calling Player:power_backpack() reshuffles the player's ammo stacks. Is there any way to do this without also turning the backpack on? It would be quite a handy feature.
Honestly, I suspect there are still bugs in power_backpack ;)  But no, I'm not aware of any other code that resorts the inventory like this; it is tied together with the backpack flag.
Logged

SPTX

  • Sergeant
  • *
  • Offline Offline
  • Posts: 77
  • Lost Soul
    • View Profile
Re: Changing the ammo system?
« Reply #13 on: March 30, 2013, 17:29 »

Speaking of sprite. Can I have the source code of the cyberdemon/spidermastermind?
I need to see how a sprite of a size bigger than one tile is handled. When I try to use them, they are cropped from their upper left corner to one tile.
Logged

tehtmi

  • Programmer
  • Local Inquisitor
  • Lieutenant Colonel
  • *
  • *
  • Offline Offline
  • Posts: 458
    • View Profile
Re: Changing the ammo system?
« Reply #14 on: March 30, 2013, 17:31 »

I need to see how a sprite of a size bigger than one tile is handled. When I try to use them, they are cropped from their upper left corner to one tile.

Give a being (or item) the flag F_LARGE to allow for an oversized sprite.
Logged
Pages: [1] 2 3 4  All