Crazy Horses: How Can I Make Mounts Explode On Death?

Users who are viewing this thread

Flanged

Sergeant Knight
The title pretty much says it all.  Does anyone know how to make a "horse" spawn a fire and smoke cloud on death, under the 1.011 module system?  I'm sure this will have been done before by someone, but it's been a while since I tried any modern-day or futuristic mods, and I can't actually remember ever seeing it done in a game... 
In fact, I will go try some of the modern mods now and see if I can figure it out myself.

But if anyone happens to have a script that would do this, lying close to hand, please help me out.

Cheers,
Flanged
 
i've never seen fire in native, but i have seen smoke, you might be able to find something in particle systems, and copy it.... and find a trigger for when horses/mounts die... but i dont know **** about particles... i'm just guessing at what sounds logical.
 
Malik Faris said:
i've never seen fire in native, but i have seen smoke, you might be able to find something in particle systems, and copy it.... and find a trigger for when horses/mounts die... but i dont know **** about particles... i'm just guessing at what sounds logical.

There's definitely fire in Native 1.011...  I just use the village_fire_big scene prop, which I can spawn quite easily when an object with the specific script attached gets destroyed.  It works exactly like you decribed, spawning a psys_particle_object.

What I really need, though, is a script or misson-template entry that will detect when a horse's hitpoints reach zero, and will then spawn the fire and smoke at the position of the horse's corpse.  It occurs to me that horses often move a small distance from where they are killed - sliding down hills or along the ground because of momentum, so it might be best if there was a slight delay before the fire and smoke appeared.

I realise it's a lot to ask, and most people who know how to do it will be keeping it for their own mods, but with what I have planned... it'll be really awesome.  :grin:
 
Although horses are agents, I'm not sure if this would trigger. This has a 0.5 second delay, but AFAIK corpse location != agent location.
Code:
(ti_on_agent_killed_or_wounded, 0.5, 0, [],
    [
      (store_trigger_param_1, ":dead_agent"),
      (neg|agent_is_human, ":dead_agent"), #is a horse
      (agent_get_item_id, ":horse", ":dead_agent"),
      (eq, ":horse", "itm_exploding_horse"),
      (agent_get_position, pos2, ":dead_agent"),
      #do particle system stuff
      (try_for_agents, ":agent"),
        (agent_is_alive, ":agent"),
        (neq, ":agent", ":dead_agent"),
        (agent_get_position,pos3,":agent"),
        (get_distance_between_positions,":dist",pos2,pos3),
        (try_begin),
           (lt, ":dist", 100), #1 meter
           #deal damage, play sound, set animation, whatever
        (try_end),
      (try_end),
    ]
  ),
 
Somebody said:
ti_on_agent_killed_or_wounded..
works only in WB. OP asked about 1.011

You can run try_for_agents every 1 sec and check if the horse agent is dead. Make a slot for the agents that indicated they were alive (fill it with "alive" id in the beginning of battle), and check both the slot=alive and neg|agent_is_alive. Then appy effects and set slot to "dead" id to not explode this corpse the second time.
 
GetAssista said:
Somebody said:
ti_on_agent_killed_or_wounded..
works only in WB. OP asked about 1.011

You can run try_for_agents every 1 sec and check if the horse agent is dead. Make a slot for the agents that indicated they were alive (fill it with "alive" id in the beginning of battle), and check both the slot=alive and neg|agent_is_alive. Then appy effects and set slot to "dead" id to not explode this corpse the second time.

Thanks guys, I will try out these various methods, modifying where necessary, and report back if I can get it working.
 
GetAssista said:
Make a slot for the agents that indicated they were alive (fill it with "alive" id in the beginning of battle), and check both the slot=alive and neg|agent_is_alive. Then appy effects and set slot to "dead" id to not explode this corpse the second time.

Haven't been able to get this working so far, and I'm starting to think I'm missing out a vital step.  GetAssista, if you happen by here, could you explain in detail what you mean by the bolded bit above?  Truth is, I'm no good with scripting at all.  I don't know where I'd make that slot for the agent (in the script I've already added, or separately in the battle's mission template?) and I'm stuck.  Thanks in advance.

Here's the script as it's currently running... it doesn't seem to have any effects:

Code:
#Car Expolsion

(.1, 0, 0, [], [
      (try_for_agents, ":dead_agent"),
         (store_mission_timer_a,":cur_time"),
         (ge, ":cur_time", 0.5), #checks for activation every 0.5 seconds
      (store_trigger_param_1, ":dead_agent"),
      (neg|agent_is_human, ":dead_agent"), #is a horse
      (agent_get_item_id, ":horse", ":dead_agent"),
      (eq, ":horse", "itm_warhorse"),
      (agent_get_position, pos1, ":dead_agent"),
      (particle_system_burst,":dead_agent", "psys_village_fire_smoke_big", pos1, 100), #100 as power.
      (try_end),
    ]),
 
Used 30 as my agent slot number, you can use anything you like to not intersect with your own slots. This should work for 1.011.
WB has better ways of doing this, through trigger on ti_on_agent_killed_or_wounded or such. Check syntax, I was typing it from memory

(.5, 0, 0, [], [
(try_for_agents, ":dead_agent"),
        (store_mission_timer_a,":cur_time"),
        (ge, ":cur_time", 0.5), #checks for activation every 0.5 seconds
      (store_trigger_param_1, ":dead_agent"),

      (neg|agent_is_human, ":dead_agent"), #is a horse
      (neg|agent_is_alive, ":dead_agent"),
      (agent_slot_eq, ":dead_agent", 30, 0),
      (agent_set_slot, ":dead_agent", 30, 1),
       

      (agent_get_item_id, ":horse", ":dead_agent"),
      (eq, ":horse", "itm_warhorse"),
      (agent_get_position, pos1, ":dead_agent"),
      (particle_system_burst,":dead_agent", "psys_village_fire_smoke_big", pos1, 100), #100 as power.
      (try_end),
    ]),
 
GetAssista said:
Used 30 as my agent slot number, you can use anything you like to not intersect with your own slots. This should work for 1.011.
WB has better ways of doing this, through trigger on ti_on_agent_killed_or_wounded or such. Check syntax, I was typing it from memory

I've added the new code, but I need to explain better what is confusing me.  When you say "Used 30 as my agent slot number, you can use anything you like so as to not intersect with your own slots,"  I'm befuddled.  Where do I find, or define, the agent's slot number?  Do I add something to the exploding warhorse itself in module_tems, so that the mission template will know what agent I want to explode?

Something like this:
["warhorse", "Police Car", [("poliscarride",0)], itp_type_horse... ...
.... ... ...
[(ti_on_init_item, [(store_trigger_param_1, ":agent_no"),(store_trigger_param_2, ":troop_no"),)])]],

Or am I way off base?

I don't have a clue how to set an agent's slot, or find out it's correct slot number.

EDIT:  Just saw, at the very end of Jik's Module Documentation "slots – All tuple objects have slots (about 240) associated with them.  They are a list of integer(numbers only) values which by default are 0.  NATIVE
assignments can be seen in module_constants.py.  If a slot number is not used, then you may assign it in the module_constants.py.  It is a bad idea to use slots that are currently assigned for different purposes."

Ah!  Maybe I need to look at module_constants, then, and assign my horse a slot.  Hopefully this will work.
 
Agent slots are defined like every other slot in module_constants. Ensure that there is no conflict with existing slots, and you should be fine setting its index to a reasonable value like 30. You can then assign it a value from almost anywhere. I'm not sure if the ti_on_init_item trigger returns the proper agent - you might have to use agent_get_item_id (a WB operation?) in conjunction with ti_on_agent_spawn (the first param is the agent) to set the initial value of that slot for that agent.
 
Flanged said:
EDIT:  Just saw, at the very end of Jik's Module Documentation "slots – All tuple objects have slots (about 240) associated with them.
This might be true for 1.011, but from my testing in warband they seem to have 1048576 slots, and the slot values can be up to 264 (though values over 232 seemed to display as 0 with display_message).
 
It doesn't seem to work, but I'll keep trying.

Need to ask a supplementary question, not worth starting a new thread - is there any way to have more than one shield_broken sound?  Currently all shields make the same sound when they break - I'd like to have a couple of variant sounds for different types of shields...  Thanks in advance if anybody can help.
 
You can try to use this script.

Code:
    (0.25, 0, 0, [],
	[
	    (try_for_agents, ":agent"),
		    (neg|agent_is_human, ":agent"), #Aka a horse.
			(try_begin),
			    (agent_is_alive, ":agent"), #If he's alive..
				(try_begin),
				    (neg|agent_slot_eq, ":agent", 50, 1), #If the agents 'slot 50' value is not '1', then continue.
					(neg|agent_slot_eq, ":agent", 50, 2), #Same as above.
					(agent_set_slot, ":agent", 50, 1), #Then set the slot value to 1 for this specific agent.
				(try_end),
			(else_try),
			    (neg|agent_is_alive, ":agent"), #If the agent isn't alive.
				(try_begin),
				    (agent_slot_eq, ":agent", 50, 1), #Agent was alive the last time this trigger ran.
					(agent_set_slot, ":agent", 50, 2),
					#Explode the horse here.
				(try_end),
			(try_end),
		(try_end),
	]),
 
Thanks Sinisterius.  I gave it a try as is, and everything compiles fine, but there is no explosion during battle, and a warning appears on screen about the consequences in the mission_template.  That might be down to something I added while trying to make the horse explode, though.

I'm going to read up on the use of slots in Jik's module system manual, because I have no real grasp of how they work.  Once I know that, I should be able to figure out what I've done wrong.  Thanks mate.
 
Think of slots like the regular Inventory in M&B. Each troop has their own Inventory and you can store something into the Inventory Slots.

So..
(agent_set_slot, <agent>, <slot>, <value>), - all it does is set the <agents> <slot> to the <value>.

Slots are defined to make the MS more human-readable..
agent_slot_x = 50
(agent_set_slot, <agent>, agent_slot_x, <value>), is exactly the same as (agent_set_slot, <agent>, 50, <value),.



Post your current script and we'll see what's wrong with it.
 
Flanged said:
I'm going to read up on the use of slots in Jik's module system manual, because I have no real grasp of how they work.  Once I know that, I should be able to figure out what I've done wrong.  Thanks mate.

For what it's worth...
Caba`drin said:
Slots are essentially ways to have variables arrayed by an object (party, troop, agent, team, faction, scene, item, player, scene prop, or party template).  Each party, troop, agent, item etc has a number of "slots" (variables) assigned to it. That variable has a common name "slot_item_SLOTNAME" for each version of the object is assigned to (items in this case), which is useful, but stores unique information for each object. Where it looks like a "constant" is the fact that the engine turns the name of the arrayed variable (the slot) into a number in module_constants (slot_item_base_price = 53).  This means that the engine looks at the 53rd slot-variable associated with a given item to find that item's base price.

So, when you see operations using slots such as (item_get_slot, ":base_price", ":item_id", slot_item_base_price),
you can see that you need to specify exactly which item you want to get the base price for. But, since the variable is arrayed, you could embed that in a try_for_* loop and iterate through many ":item_id"s to do things to the base price of every item, say.

You can access the price for a specific item with the item_get_slot operation, change it via item_set_slot, and test for equality with item_slot_eq and the like.

If you know C-like programming languages, slots work a lot like this:
slot_troop_spouse
spouse[troop1] = spousename
spouse[troop2] = spousename
spouse[trp_player] = spousename
which the engine reads as troop_variable_30[troop1], troop_variable30[trp_player] etc since slot_troop_spouse is set as slot 30 in constants.

slot_item_base_price
baseprice[item1] = priceA
baseprice[item2] = priceB
baseprice[item3] = priceC
and the engine reads that as item_variable_53[item1], item_variable_53[item2] etc...since it is set as 53 in constants
 
Sorry to necro the thread, but I'm trying to make a Hogs of War mod and this is just what I need for it.

Would it be possible to make human npcs explode upon death? I imagine it would probably overload the system, but if it's only specific type of humans, say, the hero-type character (lords, companions), then it should probably be alright. Methinks for this I'd need to remove the...
(neg|agent_is_human, ":agent"), #Aka a horse
...parameter in the above code, or at least the 'neg|' part, right? Question is, then, what parameter should I add to make it only hero-type npcs?
 
Last edited:
Sorry to necro the thread, but I'm trying to make a Hogs of War mod and this is just what I need for it.

Would it be possible to make human npcs explode upon death? I imagine it would probably overload the system, but if it's only specific type of humans, say, the hero-type character (lords, companions), then it should probably be alright. Methinks for this I'd need to remove the...

...parameter in the above code, or at least the 'neg|' part, right? Question is, then, what parameter should I add to make it only hero-type npcs?
Adding (agent_get_troop_id, ":troop", ":agent"), (troop_is_hero, ":troop"), after the (agent_is_human, ":agent"), will trigger it only for agents whose base troop has the flag tf_hero.

Make sure it is after, or else you'll get errors because horses return a troop_id of -1 and that is always an invalid troop id.
 
Adding (agent_get_troop_id, ":troop", ":agent"), (troop_is_hero, ":troop"), after the (agent_is_human, ":agent"), will trigger it only for agents whose base troop has the flag tf_hero.

Make sure it is after, or else you'll get errors because horses return a troop_id of -1 and that is always an invalid troop id.
Thank you :smile:
 
Back
Top Bottom