ProjectsWhat's NewDownloadsCommunitySupportCompany
Forum Index » S.T.A.L.K.E.R.: Clear Sky Forum » Mod discussion
Spawning animation-relevant items 'on-demand'?

1 2 | Next 10 events »| All Messages
Posted by/on
Question/AnswerMake Newest Up Sort by Descending
  13:10:45  8 March 2014
profilee-mailreply Message URLTo the Top
Decane
Senior Resident
 

 
On forum: 04/04/2007
Messages: 1706
Spawning animation-relevant items 'on-demand'?

90% or more of the NPCs in CS never use one or more of the items that is spawned on them. I want to make items like the guitar, binoculars, walkie-talkie, detector, and so on, spawn on-demand for when an NPC actually needs them, and despawn once the relevant animation has finished.

To give a very simple example: in the beginning of the game, Lebedev communicates with the trader via walkie-talkie. Well, I want to remove the walkie-talkie from Lebedev's character_desc_ configuration and instead have it spawn on him automatically whenever a walkie-talkie animation plays, and get likewise removed from him when the animation is over.

Is this feasible?
  20:51:51  8 March 2014
profilee-mailreply Message URLTo the Top
Alundaio
Sad Clown
(Resident)

 

 
On forum: 04/05/2010
Messages: 2230
Take a look in state_mgr_animation.script. Search for the process_special_action method. This is what attaches/detaches the item needed for animation. You can probably modify this to give the NPC the item if he doesn't have it. Will most likely need to switch the newly spawned item online and grab the level object. May need to keep track of the item you spawned so you can remove it when detach is called.
  18:20:07  9 March 2014
profilee-mailreply Message URLTo the Top
Decane
Senior Resident
 

 
On forum: 04/04/2007
 

Message edited by:
Decane
03/09/2014 18:21:46
Messages: 1706
Thanks for replying.

I searched through all the CS scripts with Notepad++ but I couldn't find any entries matching "process_special_action" -- might this be COP-exclusive? Anyway, I had a look in state_mgr_animation.script but the coding in that file is pretty opaque; I can't decipher where I'm supposed to put the item spawn condition. I tried inserting it into function animation:update() but that didn't seem to do anything:

for k,v in pairs(self.states.attach_items) do
	if v.done == false then
		local t = self.npc:object(k)
		if t == nil then		-- item spawn cond starts here
			alife():create(k,
			self.npc:position(),
			self.npc:level_vertex_id(),
			self.npc:game_vertex_id(),
			self.npc:id())
		end				-- item spawn cond ends here
--		while t == nil do wait() end
		if t then
			if v.mode == "attach" then
				t:enable_attachable_item(true)
			elseif v.mode == "detach" then
				t:enable_attachable_item(false)
			end
		end
	end
end

The commented code was meant to prevent the script from advancing to the 'if t then'-clause before the relevant item is spawned, but uncommenting it froze my game.
  00:32:26  10 March 2014
profilee-mailreply Message URLTo the Top
Alundaio
Sad Clown
(Resident)

 

 
On forum: 04/05/2010
 

Message edited by:
Alundaio
03/10/2014 5:11:06
Messages: 2230
It's part of set_state and update in CS, sorry. I guess they moved it into it's own function in CoP.

I cannot remember if you are able to turn an object online in the same frame you spawn it in and be able to find it's level object. This is not something I've ever needed to do. But if it is possible you'll have to do something like this:


		if v.done == false then
			local t = self.npc:object(k)
			if t then
				if v.mode == "attach" then
					t:enable_attachable_item(false)
				end
			else
				local se_itm = alife():create(k,self.npc:position(),0,0,self.npc:id())
				if (se_itm) then
					se_itm:switch_online()
					t = level.object_by_id(se_itm.id)
					if (t) then
						printf("test to see if it actually works!")
						if v.mode == "attach" then
							t:enable_attachable_item(true)
						elseif (v.mode == "detach") then
							t:enable_attachable_item(false)
						end
					else
						printf("test doesn't work!")
					end
				end
			end
			v.done = true
		end




If that doesn't work, then I assume, since this is in the update method, that you can just spawn the item and it will work on it's own next frame. This might be all you really need to do:


		if v.done == false then
			local t = self.npc:object(k)
			if t then
				if v.mode == "attach" then
					t:enable_attachable_item(true)
				elseif (v.mode) == "detach" then
					t:enable_attachable_item(false)
				end
				v.done = true
			else
				alife():create(k,self.npc:position(),0,0,self.npc:id())
			end
		end



Note how I moved v.done = true. This means this will keep executing until it finds the object in the inventory to attach. In theory this means there is no reason to immediately find the level object of the item you just spawned, it should find it automatically next update. But if it doesn't find it, it may keep spawning new items until it does, that could be bad. Throw a debug printf statement there to make sure it's working correctly.


The rest is up to you. You can either keep track of the items you had to spawn or just remove all the attachable items from NPC inventory, regardless if you had to spawn them or not. If in your mod there is no reason to have guitar, binocs, harmonica, radio and pda then there is no reason to remember. Just release them all wherever it is detached.

For whatever reason you want some NPCs to have guitars, harmonicas and crap like that in their inventory then you should create new item sections for them instead. Keep the originals for attaching/detaching on demand only. Will be much easier to implement this feature. Might not want to release food/drink items though.

I really like this idea, and I think I will implement this into my own mod. This is a good way to save lots of game object ids and memory. You could delete all the worthless items from character descriptions.

EDIT:
Switching online after creation won't work. I just tested this myself. The second example should probably work though. If not I do have a solution that I am using for CoP.
  03:14:44  13 March 2014
profilee-mailreply Message URLTo the Top
Decane
Senior Resident
 

 
On forum: 04/04/2007
Messages: 1706
Alundaio, I got the item spawns and despawns working for all NPCs except those sitting by campfire. For some reason, campfire NPCs seem totally unaffected: when I remove all the regular campfire clutter (e.g. guitars, food items) from their character descriptions, they never spawn any of it and never perform any of the usual accommodating animations despite the script working as intended for all non-campfire NPCs.

Also, I have a strange problem with my torch spawner: each time I reload a savegame where it is dark outside (and NPCs are set to have torches active), a bunch of torches are spawned and activated according to my in-game debug message log, without however showing up as such when I look around in-game, and without being released subsequently. I suspect that these are campfire NPC torches, but I don't understand why they are not being released. If you could have a look, I have uploaded my sr_light.script here: http://pastebin.com/GVGQ5iJQ. It should work as-is, in case you have CS installed and want to test it. In-game debug messages are enabled, as well.
  04:43:45  13 March 2014
profilee-mailreply Message URLTo the Top
Alundaio
Sad Clown
(Resident)

 

 
On forum: 04/05/2010
Messages: 2230
Look in xr_kamp.script CKampManager:checkNpcAbility. There are preconditions to use the various camp animations. Simply remove them.


It says your paste has been removed.
  11:59:15  13 March 2014
profilee-mailreply Message URLTo the Top
Decane
Senior Resident
 

 
On forum: 04/04/2007
Messages: 1706
Ok, I will look in xr_kamp.

And sorry about the paste; the forum software included the period in the URL for some reason, so it didn't work. Here: http://pastebin.com/GVGQ5iJQ
  14:17:15  13 March 2014
profilee-mailreply Message URLTo the Top
Alundaio
Sad Clown
(Resident)

 

 
On forum: 04/05/2010
Messages: 2230
Should work, tested in CoP though: http://pastebin.com/PD52CFjX


Another idea I like. *steal*
  20:37:34  13 March 2014
profilee-mailreply Message URLTo the Top
Decane
Senior Resident
 

 
On forum: 04/04/2007
 

Message edited by:
Decane
03/13/2014 20:52:45
Messages: 1706
All right, I got everything working. Now if you don't mind, I have a couple of questions.

(1) What happens when a stalker switches offline with an item enabled? Will the item be saved on the NPC? If so, can we release it upon the NPC turning offline?

(2) In your sr_light.script, you localized alife() at the top of the function check_light(), instead of nesting it as deep into the conditional clauses as you could. Why? Won't the game then unnecessarily localize alife() each time the function is called to simply enable the torch? Does it matter for performance whether it is localized at the top of the function vs. inside a conditional, assuming that it is called?

(3) You did not use the function attachable_item_enabled() to prevent cases where an NPC with his torch already enabled would have his torch repeatedly re-enabled by the script. Why? Is it more performance-costly to conditionalize the enabling on attachable_item_enabled() ~= true than letting the script enable the torch regardless of whether it is already on or not?

(4) You used this:
sim:create("device_torch", vector(), 0, 0, stalker:id())

Instead of:
sim:create("device_torch",
	stalker:position(),
	stalker:level_vertex_id(),
	stalker:game_vertex_id(),
	stalker:id())

Why? I presume it is more efficient, but is it guaranteed to always work?

That's all I have for now. Many thanks for your help!

EDIT:

(5) Actually, I do have one more question: I sometimes get some stutter when the game spawns / unspawns an item -- any way to get rid of it?
  23:40:40  13 March 2014
profilee-mailreply Message URLTo the Top
Alundaio
Sad Clown
(Resident)

 

 
On forum: 04/05/2010
 

Message edited by:
Alundaio
03/13/2014 23:43:18
Messages: 2230

---QUOTATION---
All right, I got everything working. Now if you don't mind, I have a couple of questions.

(1) What happens when a stalker switches offline with an item enabled? Will the item be saved on the NPC? If so, can we release it upon the NPC turning offline?

---END QUOTATION---


Not sure. But I actually did do this in my version:


		if (torch) then
			torch:enable_attachable_item(false)
			sim:release(sim:object(torch:id()),true)
		end




---QUOTATION---

(2) In your sr_light.script, you localized alife() at the top of the function check_light(), instead of nesting it as deep into the conditional clauses as you could. Why? Won't the game then unnecessarily localize alife() each time the function is called to simply enable the torch? Does it matter for performance whether it is localized at the top of the function vs. inside a conditional, assuming that it is called?
---END QUOTATION---


Yes, you should localize it in the smallest scope, but I did that for ease because I wrote this up pretty fast.


---QUOTATION---

(3) You did not use the function attachable_item_enabled() to prevent cases where an NPC with his torch already enabled would have his torch repeatedly re-enabled by the script. Why? Is it more performance-costly to conditionalize the enabling on attachable_item_enabled() ~= true than letting the script enable the torch regardless of whether it is already on or not?

---END QUOTATION---


Yeah, you should put
			if not (torch:attachable_item_enabled()) then
				torch:enable_attachable_item(true)
			end




---QUOTATION---

(4) You used this:
sim:create("device_torch", vector(), 0, 0, stalker:id())

Instead of:
sim:create("device_torch",
	stalker:position(),
	stalker:level_vertex_id(),
	stalker:game_vertex_id(),
	stalker:id())

Why? I presume it is more efficient, but is it guaranteed to always work?

---END QUOTATION---


Yes, it should always work as long as ID is valid. If the create method is overloaded with an ID field it will set the spawned object's parent as that id. Passing the position, lvid and gvid aren't necessary, they can be zero'd out.

That's all I have for now. Many thanks for your help!

---END QUOTATION---


---QUOTATION---

EDIT:

(5) Actually, I do have one more question: I sometimes get some stutter when the game spawns / unspawns an item -- any way to get rid of it?
---END QUOTATION---



Do you have prefetching disabled? You can try adding this to the top of sr_light.script:

	local st = db.storage[stalker:id()]
	local tg = time_global()
	
	if (st.srlight_timer and tg < st.srlight_timer) then
		return
	end
	st.srlight_timer = tg + 1000 + math.random(100)



The random is just so all the updates don't run at same time.
 
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.: Clear Sky 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.