ProjectsWhat's NewDownloadsCommunitySupportCompany
Forum Index » S.T.A.L.K.E.R.: Shadow of Chernobyl Forum » Mod discussion
Having items not spawn on death.

Posted by/on
Question/AnswerMake Newest Up Sort by Descending
  22:00:28  26 April 2013
profilee-mailreply Message URLTo the Top
FatalFunnel
(Senior)
 
On forum: 11/07/2011
Messages: 133
Having items not spawn on death.

So how do I go about doing this?

I currently have an item that is supposed to spawn on NPCs, but I want that item to be "hidden" so that it doesn't show up on corpses when they die. is there some sort of specific place or integer in the death_items configs where I could make this happen?
  02:05:31  27 April 2013
profilee-mailreply Message URLTo the Top
NatVac
Senior Resident
 

 
On forum: 06/15/2007
Messages: 4302
What do you mean "spawn on NPCs"? Spawn in their inventories when they spawn? Or spawn on their bodies?

If the former, it should automatically be removed via death_manager.script when they die, without having to add it to the death_*.ltx files. And if you do't want it added, you should remove it from those files.

As for hiding items that are spawned: That is probably not what you meant as it does not make sense to me. If you hide an item on a corpse, it is not available to you; might as well be deleted. (There's a bug that hides an item of food or drink on a corpse from time to time. It makes folks think that it is spawning there or another NPC put it there.)

If you do want to spawn it hidden after their death, I would like to understand why.
  04:17:28  2 May 2013
profilee-mailreply Message URLTo the Top
FatalFunnel
(Senior)
 
On forum: 11/07/2011
Messages: 133

---QUOTATION---
What do you mean "spawn on NPCs"? Spawn in their inventories when they spawn? Or spawn on their bodies?

If the former, it should automatically be removed via death_manager.script when they die, without having to add it to the death_*.ltx files. And if you do't want it added, you should remove it from those files.
---END QUOTATION---



No, you're definitely right here, I don't know what I was thinking when I phrased this, so I guess what I need to do here with the death_manager.script is have them de-spawn on NPC death.

Basically what I did here was I made a copy of the default medkit to spawn on NPCs, so that they have something to use, since my alterations to the default medkits make it impossible for NPCs to heal themselves with, the default medkits now exist solely for the actor to use, and not NPCs, this screws up healing NPCs but I'll get to that later.

In other words, I had to clone the old medkit properties for every entity in the game except the actor, but I want to modify these particular medkits to de-spawn on corpses.

So the way this whole mechanic works is that the player is supposed to use one type of medkit in a unique way, but NPCs use a clone of the original medkit the vanilla way, and since they are supposed to de-spawn, the player is not ever intended to interact with these "phantom-medkits."


Now, on to the matter of it breaking healing, is xr_wounded.script the correct one that is handled by the dialog option? Since I changed the way that medkits work, giving an NPC a medkit doesn't heal them, since the actor medkits don't have any healing properties of their own.

Even with that, I still want to alter them so that they take the actor's medkit, then spawn the copy medkit in their inventory, which is then used to heal them. In other words, the system exchanges one medkit for another, instead of just taking the actor's medkit and healing them with that.

I noticed this section in xr_wounded.script, I don't know if it's the right one, but I've altered it slightly.



function Cwound_manager:eat_medkit()
  if self.can_use_medkit == true then
    local medkit_eaten=false
    if self.npc:object("medkit") ~= nil then
      self.npc:eat(self.npc:object("medkit_b"))
      medkit_eaten=true
    elseif self.npc:object("medkit_army") ~= nil then
      self.npc:eat(self.npc:object("medkit_army_b"))
      medkit_eaten=true
    elseif self.npc:object("medkit_scientic") ~= nil then
      self.npc:eat(self.npc:object("medkit_scientic_b"))
      medkit_eaten=true
    end




Like I said, I don't know if this is even the correct section of the script, I'm just testing theoretics, but between the medkit, and medkit_b (medkit_b being the copy) I was thinking of inserting a line to spawn medkit_b in that NPC's inventory and then testing it out in game, though I still have to figure out what that particular spawn command is.
  06:11:06  9 May 2013
profilee-mailreply Message URLTo the Top
NatVac
Senior Resident
 

 
On forum: 06/15/2007
 

Message edited by:
NatVac
05/09/2013 6:19:04
Messages: 4302
You have a lot of complications here.

---QUOTATION---
I guess what I need to do here with the death_manager.script is have them de-spawn on NPC death.
---END QUOTATION---


That's what the original death_manager did. The one you included in your "ZoA 1.07 ai merge scripts" archive is specifically testing for stuff and deleting it while the original deleted everything but the slotted guns.

I'd normally suggest going back to the original, but AMK has this looting thing and you probably want to keep all the weapons on the bodies. Well, then, test the section for "wpn_" and if match, test for "wpn_binoc" and if not match then return. Let the normal alife():release() take care of the rest.

You have this:
__________
        -- óäàëÿòü ÏÄÀ, ãèòàðó\ãàðìîøêó, ôîíàðèêè è ïðèáîðû íî÷íîãî âèäåíèÿ, ðàöèþ, áèíîêëü.
        if (section == "device_torch" or section == "device_pda" or section == "hand_radio" or
            section == "guitar_a" or section == "harmonica_a" or section == "binocular_a" or
            section =="wpn_knife" or section == "wpn_binoc" or section=="bolt") then
                --if (npc.mark_item_dropped) then
--    npc:mark_item_dropped(item)
                --end
    alife():release(alife():object(item:id()), true)
end
end

¯¯¯¯¯¯¯¯¯¯
Note the misleading formatting again.

Replace that with this:
__________
  if string.find(section, "wpn_",1,true) then --weapon
    if section ~= "wpn_binoc" and section ~= "wpn_knife" then 
      return true -- keep all weapons except binocs (and knives?)
    end
  end
  -- this removes everything else, before the game starts adding inventory
  alife():release(alife():object(item:id()), true)
end

¯¯¯¯¯¯¯¯¯¯
That deletes everything but the guns. Everything else should be handled automatically. If you do want to keep something, you can check for it before the release; return true if match, fall through to delete if not. Otherwise consider adding it to the keep_items section in config\misc\death_generic.ltx.

On NPCs and medkit usage:

---QUOTATION---
"... the cost of adding a feature isn't just the time it takes to code it. The cost also includes the addition of an obstacle to future expansion. ... The trick is to pick the features that don't fight each other." -- John Carmack
---END QUOTATION---


The Rulix/bak/xStream stuff puts medkits and bandages on NPCs automatically, so they can heal themselves eventually if your event loop is working correctly. And yad/rx_attach_bandage are derived from medkit/bandage.

You will need to go through all that new code and replace the medkit* and bandage stuff with your clones. Same for the normal medkit management stuff, like in xr_wounded.script, some of which is discussed below. You will have to be logically careful here. I suggest changing only the [yad]:medkit and [rx_attach_bandage]:bandage section definition dependencies (replace medkit with medkit_b and bandage with bandage_b or whatever there) and every place in the Rulix/AIPack code where the medkit stuff is in quotes: "medkit" -> "medkit_b", etc. only where NPC-related.

That will fix the NPC self-healing and NPC-healing-NPC stuff.

For your healing NPCs via dialog: My recommendation here is to spawn a special medkit clone on the NPC, like medkit_scientic_b (for 100% healing at master level), when you open a dialog with the wounded individual. (It won't matter that much if you can't or don't heal them, but we can discuss refinements after you get it working.)

One way to give them the right medkit: in xr_motivator.script in the use_callback() function, after the line xr_use.notify_on_use(obj, who) you could insert a block that checks the wounded status and adds a medkit if necessary, like so:
__________
    if xr_wounded.is_wounded(self.object) then
      local npc = self.object
      if npc:object("medkit_scientic_b") == nil then
        alife():create("medkit_scientic_b",npc:position(),
              npc:level_vertex_id(),npc:game_vertex_id(),npc:id())
      end
    end

¯¯¯¯¯¯¯¯¯¯
Now change dialogs.script's transfer_medkit() function from this:
__________
function transfer_medkit(first_speaker, second_speaker)
	if first_speaker:object("medkit") ~= nil then
		dialogs.relocate_item_section(second_speaker, "medkit", "out")
	elseif first_speaker:object("medkit_army") ~= nil then
		dialogs.relocate_item_section(second_speaker, "medkit_army", "out")
	else
		dialogs.relocate_item_section(second_speaker, "medkit_scientic", "out")
	end

¯¯¯¯¯¯¯¯¯¯
to this:
__________
function transfer_medkit(first_speaker, second_speaker)
  local medkit_obj = first_speaker:object("medkit") or first_speaker:object("medkit_army") or
      first_speaker:object("medkit_scientic")
  if medkit_obj ~= nil then
    alife():release(alife():object(medkit_obj, true))
  end

¯¯¯¯¯¯¯¯¯¯
That releases the normal medkit that you would have transferred to the NPC. The rest of the code will enable him to consume the one you put on him in xr_motivator.script.

Then use a MODIFIED version of your code to check if the NPC has his kind of medkit (e.g., medkit_b/medkit_scientic_b/medkit_army_b), then have the npc eat it -- normally the medkit*_b you spawned on him.
__________
function Cwound_manager:eat_medkit()
  if self.can_use_medkit == true then
    local medkit_eaten=false
    if self.npc:object("medkit_b") ~= nil then
      self.npc:eat(self.npc:object("medkit_b"))
      medkit_eaten=true
    elseif self.npc:object("medkit_army_b") ~= nil then
      self.npc:eat(self.npc:object("medkit_army_b"))
      medkit_eaten=true
    elseif self.npc:object("medkit_scientic_b") ~= nil then
      self.npc:eat(self.npc:object("medkit_scientic_b"))
      medkit_eaten=true
    end

¯¯¯¯¯¯¯¯¯¯
Again: note that the code checks for the right kind of object before allowing the NPC to eat it. Otherwise there will be an occasional crash.

It may be possible to create and consume a medkit in the same execution block, but I've found that to be unreliable. The item spawned needs to become real before it can be "used" or "eaten".

Disclaimers: This code has not been tested. I'm suffering from allergies and bad eyesight at the moment; check for typos. I've edited and slightly reformatted this for appearance but it should not affect code execution if properly cut/pasted.
  23:28:37  9 June 2013
profilee-mailreply Message URLTo the Top
FatalFunnel
(Senior)
 
On forum: 11/07/2011
Messages: 133

---QUOTATION---
Replace that with this:
__________
  if string.find(section, "wpn_",1,true) then --weapon
    if section ~= "wpn_binoc" and section ~= "wpn_knife" then 
      return true -- keep all weapons except binocs (and knives?)
    end
  end
  -- this removes everything else, before the game starts adding inventory
  alife():release(alife():object(item:id()), true)
end

¯¯¯¯¯¯¯¯¯¯
That deletes everything but the guns. Everything else should be handled automatically. If you do want to keep something, you can check for it before the release; return true if match, fall through to delete if not. Otherwise consider adding it to the keep_items section in config\misc\death_generic.ltx.
---END QUOTATION---



So it deletes everything but the guns, that's much better than my edits to add it to the list separated with commas, like binocs, knife, etc. since that gave me a crash.


---QUOTATION---
On NPCs and medkit usage:
"... the cost of adding a feature isn't just the time it takes to code it. The cost also includes the addition of an obstacle to future expansion. ... The trick is to pick the features that don't fight each other." -- John Carmack
The Rulix/bak/xStream stuff puts medkits and bandages on NPCs automatically, so they can heal themselves eventually if your event loop is working correctly. And yad/rx_attach_bandage are derived from medkit/bandage.

You will need to go through all that new code and replace the medkit* and bandage stuff with your clones. Same for the normal medkit management stuff, like in xr_wounded.script, some of which is discussed below. You will have to be logically careful here. I suggest changing only the [yad]:medkit and [rx_attach_bandage]:bandage section definition dependencies (replace medkit with medkit_b and bandage with bandage_b or whatever there) and every place in the Rulix/AIPack code where the medkit stuff is in quotes: "medkit" -> "medkit_b", etc. only where NPC-related.

That will fix the NPC self-healing and NPC-healing-NPC stuff.
---END QUOTATION---



I already replaced the conventional medkits with their clones in the self-healing scripts, but I don't really know how well these work, but I'm glad you took the precaution to point this out.




---QUOTATION---
For your healing NPCs via dialog: My recommendation here is to spawn a special medkit clone on the NPC, like medkit_scientic_b (for 100% healing at master level), when you open a dialog with the wounded individual. (It won't matter that much if you can't or don't heal them, but we can discuss refinements after you get it working.)

One way to give them the right medkit: in xr_motivator.script in the use_callback() function, after the line xr_use.notify_on_use(obj, who) you could insert a block that checks the wounded status and adds a medkit if necessary, like so:
__________
    if xr_wounded.is_wounded(self.object) then
      local npc = self.object
      if npc:object("medkit_scientic_b") == nil then
        alife():create("medkit_scientic_b",npc:position(),
              npc:level_vertex_id(),npc:game_vertex_id(),npc:id())
      end
    end

¯¯¯¯¯¯¯¯¯¯
Now change dialogs.script's transfer_medkit() function from this:
__________
function transfer_medkit(first_speaker, second_speaker)
	if first_speaker:object("medkit") ~= nil then
		dialogs.relocate_item_section(second_speaker, "medkit", "out")
	elseif first_speaker:object("medkit_army") ~= nil then
		dialogs.relocate_item_section(second_speaker, "medkit_army", "out")
	else
		dialogs.relocate_item_section(second_speaker, "medkit_scientic", "out")
	end

¯¯¯¯¯¯¯¯¯¯
to this:
__________
function transfer_medkit(first_speaker, second_speaker)
  local medkit_obj = first_speaker:object("medkit") or first_speaker:object("medkit_army") or
      first_speaker:object("medkit_scientic")
  if medkit_obj ~= nil then
    alife():release(alife():object(medkit_obj, true))
  end

¯¯¯¯¯¯¯¯¯¯
That releases the normal medkit that you would have transferred to the NPC. The rest of the code will enable him to consume the one you put on him in xr_motivator.script.
---END QUOTATION---



So I see what this does, first it checks the NPC's state to see if they are wounded, and if they are it uses the dialog to transfer medkits to them, and then it releases the object once they have used the other type of medkit.


---QUOTATION---
Then use a MODIFIED version of your code to check if the NPC has his kind of medkit (e.g., medkit_b/medkit_scientic_b/medkit_army_b), then have the npc eat it -- normally the medkit*_b you spawned on him.
__________
function Cwound_manager:eat_medkit()
  if self.can_use_medkit == true then
    local medkit_eaten=false
    if self.npc:object("medkit_b") ~= nil then
      self.npc:eat(self.npc:object("medkit_b"))
      medkit_eaten=true
    elseif self.npc:object("medkit_army_b") ~= nil then
      self.npc:eat(self.npc:object("medkit_army_b"))
      medkit_eaten=true
    elseif self.npc:object("medkit_scientic_b") ~= nil then
      self.npc:eat(self.npc:object("medkit_scientic_b"))
      medkit_eaten=true
    end

¯¯¯¯¯¯¯¯¯¯
Again: note that the code checks for the right kind of object before allowing the NPC to eat it. Otherwise there will be an occasional crash.

It may be possible to create and consume a medkit in the same execution block, but I've found that to be unreliable. The item spawned needs to become real before it can be "used" or "eaten".

Disclaimers: This code has not been tested. I'm suffering from allergies and bad eyesight at the moment; check for typos. I've edited and slightly reformatted this for appearance but it should not affect code execution if properly cut/pasted.
---END QUOTATION---



Okay now, so this second part of the script checks to see if the first part is executed, and then it proceeds, thank you so much. I'm going to test this out. Of course, I don't know if it will work, but I'm thankful to have your help.

In the future I'm not going to take as many ambitious steps I've tried and largely failed to without at least having hired a scripter before hand.
  07:10:19  21 June 2013
profilee-mailreply Message URLTo the Top
NatVac
Senior Resident
 

 
On forum: 06/15/2007
Messages: 4302

---QUOTATION---
So I see what this does, first it checks the NPC's state to see if they are wounded, and if they are it uses the dialog to transfer medkits to them, and then it releases the object once they have used the other type of medkit.
---END QUOTATION---


Well, not exactly. First it checks to see if the NPC is wounded in xr_motivator.script's use_callback() function; if so it gives the NPC the type of scientific medkit (with the "_b" suffix) that he can use, if he does not already have one. It does this as the healing dialog is being shown -- you haven't agreed to heal him yet. Note: This function is dependent on the actor_have_medkit() function in dialogs.script remaining vanilla (no "_b" suffix check).

If you select "Here, have a medkit" in the displayed dialog to help him out, that will invoke the transfer_medkit() function in dialogs.script. That function will make a normal medkit disappear from your inventory, faking a normal medkit transfer.

It then calls xr_wounded.unlock_medkit(), at least in vanilla. That function will set can_use_medkit to true in the Cwound_manager class instance for the NPC. The normal wounded update processing will call wound_manager:eat_medkit() in xr_wounded.script, the one shown in my previous post which supports the new "_b" medkits. He will have a scientific "_b" medkit because it was spawned in his inventory above if needed.

That will heal him.
  03:58:59  29 June 2013
profilee-mailreply Message URLTo the Top
NatVac
Senior Resident
 

 
On forum: 06/15/2007
Messages: 4302

---QUOTATION---
In the future I'm not going to take as many ambitious steps I've tried and largely failed to without at least having hired a scripter before hand.
---END QUOTATION---


Sounds like wisdom borne of the reasoned contemplation of experience. There's that Fred Brooks saying to the effect that "Good judgment comes from experience, and experience comes from bad judgment."

I know it is hard to make someone else's ideas work when dealing with an unfamiliar language even when one is a programmer. If you are still having trouble with this, you can do what you did with the AI issues: post the related files online someplace where I can easily get them. While I still don't have your mod, I'm fairly good at troubleshooting and fixing code when I have enough of it.

<Insert "had enough of it already" joke here...>
 
Each word should be at least 3 characters long.
Search:    
Search conditions:    - spaces as AND    - spaces as OR   
 
Forum Index » S.T.A.L.K.E.R.: Shadow of Chernobyl Forum » Mod discussion
 

All short dates are in Month-Day-Year format.


 

Copyright © 1995-2021 GSC Game World. All rights reserved.
This site is best viewed in Internet Explorer 4.xx and up and Javascript enabled. Webmaster.
Opera Software products are not supported.
If any problem concerning the site functioning under Opera Software appears apply
to Opera Software technical support service.