View Single Post
Author Message
Hawk552
AMX Mod X Moderator
Join Date: Aug 2005
Old 09-08-2007 , 17:17   [HOWTO] Dead Bodies
Reply With Quote #1

This tutorial assumes you're an intermediate level scripter and will not explain basic syntax, logic, etc.

I'm going to be explaining how to make a dead body on top of the body that normally is on the ground after someone dies. It's sorta hacky, but I've found it works pretty well. Problems I've had with my method shouldn't cause any trouble in CS, since my implementations have been done in TS. This implementation is designed to be mod inspecific.

The first thing you have to do is hook the DeathMsg event, obviously. However, a delay must be added, otherwise the body will just instantly appear when someone dies - as if they fell over at lightspeed.

Code:
public plugin_init() {     register_plugin("Murder Mod","1.0","Hawk552")         register_event("DeathMsg","EventDeathMsg","a") } public EventDeathMsg()     set_task(2.0,"DelayedDeathMsg",read_data(2))

With this in place, we can now detect when a player dies, and (hopefully) after the animation has taken place. The first problem arises from getting rid of the player's body. This can easily be solved in CS by blocking the ClCorpse message (I think, haven't tried it). In other mods, however, you have to drop the origin of the player and the dead body will follow.

Code:
public DelayedDeathMsg(id) {        new Float:Origin[3]     entity_get_vector(id,EV_VEC_origin,Origin)         Origin[2] -= 40.0     entity_set_origin(id,Origin)     Origin[2] += 40.0 }

Now that the player's corpse is out of the way, we're going to spawn another entity to take its place. I'd use a message, but we want it to be able to have a box with which players can't move into and other stuff (for example a name of the person that died when you mouse-over the corpse).

Code:
public DelayedDeathMsg(id) {        new Float:Origin[3],Float:Angle[3],Model[33]     entity_get_vector(id,EV_VEC_origin,Origin)     entity_get_vector(id,EV_VEC_v_angle,Angle)     entity_get_string(id,EV_SZ_model,Model,32)         Origin[2] -= 40.0     entity_set_origin(id,Origin)     Origin[2] += 40.0         new Ent = create_entity("info_target")         entity_set_string(Ent,EV_SZ_classname,"dead_body")     entity_set_model(Ent,Model)     entity_set_int(Ent,EV_INT_movetype,MOVETYPE_FLY)     entity_set_int(Ent,EV_INT_sequence,100)     entity_set_size(Ent,Float:{-6.0,-12.0,-6.0},Float:{6.0,12.0,6.0})     entity_set_int(Ent,EV_INT_solid,SOLID_BBOX)     entity_set_vector(Ent,EV_VEC_v_angle,Angle)     entity_set_edict(Ent,EV_ENT_owner,id)         entity_set_origin(Ent,Origin)     drop_to_floor(Ent)     entity_get_vector(Ent,EV_VEC_origin,Origin)     Origin[2] += 13.0     entity_set_origin(Ent,Origin) }

A couple notes: I don't know why I set it to MOVETYPE_FLY, so you can probably get rid of that. Also, it may be more effective to run a trace_line to the ground and just add 13.0 units to the z value of the result, but I figure it's less work for a marginal optimization when you just use drop_to_floor.

So that's basically it on how to do it. You can add some more stuff like a timer that'll get rid of it after a certain time (so the server doesn't get too crowded or crash due to too many ents). The finished plugin (based on my Murder Mod, an unreleased plugin for TSRP) would look something like this:

Code:
#include <amxmodx> #include <amxmisc> #include <engine> new g_ClassName[] = "dead_body" new p_Time public plugin_init() {     register_plugin("Dead Bodies","1.0","Hawk552")         register_event("DeathMsg","EventDeathMsg","a")         p_Time = register_cvar("amx_body_time","60.0") } public EventDeathMsg()     set_task(2.0,"DelayedDeathMsg",read_data(2)) public DelayedDeathMsg(id) {        new Float:Origin[3],Float:Angle[3],Model[33]     entity_get_vector(id,EV_VEC_origin,Origin)     entity_get_vector(id,EV_VEC_v_angle,Angle)     entity_get_string(id,EV_SZ_model,Model,32)         Origin[2] -= 40.0     entity_set_origin(id,Origin)     Origin[2] += 40.0         new Ent = create_entity("info_target")         entity_set_string(Ent,EV_SZ_classname,g_ClassName)     entity_set_model(Ent,Model)     entity_set_int(Ent,EV_INT_movetype,MOVETYPE_FLY)     entity_set_int(Ent,EV_INT_sequence,100)     entity_set_size(Ent,Float:{-6.0,-12.0,-6.0},Float:{6.0,12.0,6.0})     entity_set_int(Ent,EV_INT_solid,SOLID_BBOX)     entity_set_float(Ent,EV_FL_nextthink,1.0)     entity_set_vector(Ent,EV_VEC_v_angle,Angle)     entity_set_edict(Ent,EV_ENT_owner,id)         entity_set_origin(Ent,Origin)     drop_to_floor(Ent)     entity_get_vector(Ent,EV_VEC_origin,Origin)     Origin[2] += 13.0     entity_set_origin(Ent,Origin)             set_task(get_pcvar_float(p_Time),"EntRemove",Ent) } public EntRemove(Ent)     remove_entity(Ent)

Some general notes:

This method has not been tested on anything other than TS, but it should generally be mod inspecific. I really doubt this would work on CS, but with a few tweaks it probably would. You can also use mod specific messages (as I stated prior to this), but you lose some functionality and portability. Also, the sequence used (100) is for TS only and will have to be changed for any other mod.

As always, if you have any questions, comments or whatever, post them up.
__________________

Last edited by Hawk552; 09-08-2007 at 17:18. Reason: added comment
Hawk552 is offline
Send a message via AIM to Hawk552