#include static enum E_CORPSE_INJURY_DATA { E_CORPSE_INJURY_HITS, E_CORPSE_INJURY_WEAPON, E_CORPSE_INJURY_BODYPART, E_CORPSE_INJURY_SECONDS, } static CorpseInjuryInfo[MAX_ACTORS][MAX_INJURIES][E_CORPSE_INJURY_DATA]; static Float:LastX[MAX_PLAYERS]; static Float:LastY[MAX_PLAYERS]; static Float:LastZ[MAX_PLAYERS]; static Float:LastA[MAX_PLAYERS]; static DraggingCorpse[MAX_PLAYERS]; static bool:BeingDragged[MAX_ACTORS]; static bool:IsACorpse[MAX_ACTORS]; static Text3D:CorpseTD[MAX_ACTORS]; static bool:ValidCorpseTD[MAX_ACTORS]; hook OnPlayerConnect(playerid) { DraggingCorpse[playerid] = INVALID_ACTOR_ID; } hook OnPlayerDisconnect(playerid, reason) { if(DraggingCorpse[playerid] != INVALID_ACTOR_ID) { if(IsValidActor(DraggingCorpse[playerid])) { Corpse_Drop(DraggingCorpse[playerid]); } DraggingCorpse[playerid] = INVALID_ACTOR_ID; } } hook OnPlayerWounded(playerid) { if(DraggingCorpse[playerid] != INVALID_ACTOR_ID) { if(IsValidActor(DraggingCorpse[playerid])) { Corpse_Drop(DraggingCorpse[playerid]); } DraggingCorpse[playerid] = INVALID_ACTOR_ID; } } hook OnPlayerEnterVehicle(playerid, vehicleid, ispassenger) { if(DraggingCorpse[playerid] != INVALID_ACTOR_ID) { if(IsValidActor(DraggingCorpse[playerid])) { Corpse_Drop(DraggingCorpse[playerid]); } DraggingCorpse[playerid] = INVALID_ACTOR_ID; } } Corpse_ShowInjuries(playerid, corpseid) { new string[112 * MAX_INJURIES]; new weaponName[36]; new count = 0; for(new i; i < MAX_INJURIES; i++) { if(CorpseInjuryInfo[corpseid][i][E_CORPSE_INJURY_HITS] != 0) { count++; GetWeaponName(CorpseInjuryInfo[corpseid][i][E_CORPSE_INJURY_WEAPON], weaponName, sizeof(weaponName)); strcat(string, va_return("{b3b3b3}%d hits from a %s to the %s, %ds ago\n", CorpseInjuryInfo[corpseid][i][E_CORPSE_INJURY_HITS], weaponName, GetBodypartName(CorpseInjuryInfo[corpseid][i][E_CORPSE_INJURY_BODYPART]), gettime() - CorpseInjuryInfo[corpseid][i][E_CORPSE_INJURY_SECONDS])); } } if(count > 0) Dialog_Show(playerid, DIALOG_STYLE_LIST, va_return("Corpse injuries (( ID %d ))", corpseid), string, "Close"); else { SendErrorMessage(playerid, "There is no damage to display."); } return 1; } Corpse_Create(playerid) { if(DraggingCorpse[playerid] != INVALID_ACTOR_ID) { if(IsValidActor(DraggingCorpse[playerid])) ApplyActorAnimation(DraggingCorpse[playerid], "CRACK", "CRCKDETH4", 4.1, 0, 1, 1, 1, 0); DraggingCorpse[playerid] = INVALID_ACTOR_ID; } new Float:x, Float:y, Float:z, Float:a; GetPlayerPos(playerid, x, y, z); GetPlayerFacingAngle(playerid, a); new corpseid = CreateActor(Player_GetSkin(playerid), x, y, z, a); ApplyActorAnimation(corpseid, "CRACK", "CRCKDETH4", 4.1, 0, 1, 1, 1, 0); BeingDragged[corpseid] = false; IsACorpse[corpseid] = true; for(new i; i < MAX_INJURIES; i++) { CorpseInjuryInfo[corpseid][i][E_CORPSE_INJURY_HITS] = InjuryInfo[playerid][i][E_INJURY_HITS]; CorpseInjuryInfo[corpseid][i][E_CORPSE_INJURY_WEAPON] = InjuryInfo[playerid][i][E_INJURY_WEAPON]; CorpseInjuryInfo[corpseid][i][E_CORPSE_INJURY_BODYPART] = InjuryInfo[playerid][i][E_INJURY_BODYPART]; CorpseInjuryInfo[corpseid][i][E_CORPSE_INJURY_SECONDS] = InjuryInfo[playerid][i][E_INJURY_SECONDS]; } if(!ValidCorpseTD[corpseid]) { ValidCorpseTD[corpseid] = true; CorpseTD[corpseid] = Create3DTextLabel("(( This is a dead body,\n/corpse examine for more information ))", 0xFF6666FF, x, y, z, 20, GetPlayerVirtualWorld(playerid), 1); } return corpseid; } Corpse_Drop(corpseid) { if(ValidCorpseTD[corpseid]) { new Float:x, Float:y, Float:z; GetActorPos(corpseid, x, y, z); Delete3DTextLabel(CorpseTD[corpseid]); CorpseTD[corpseid] = Create3DTextLabel("(( This is a dead body,\n/corpse examine for more information ))", 0xFF6666FF, x, y, z - 1, 20, GetActorVirtualWorld(corpseid), 1); } BeingDragged[corpseid] = false; ApplyActorAnimation(corpseid, "CRACK", "CRCKDETH4", 4.1, 0, 1, 1, 1, 0); return 1; } timer UpdateCorpse[100](playerid) { if(DraggingCorpse[playerid] != INVALID_ACTOR_ID && IsValidActor(DraggingCorpse[playerid])) { new corpseid = DraggingCorpse[playerid]; if(IsACorpse[corpseid]) { new Float:x, Float:y, Float:z, Float:a; GetPlayerPos(playerid, x, y, z); GetPlayerFacingAngle(playerid, a); if(x != LastX[playerid] || y != LastY[playerid] || z != LastZ[playerid] || a != LastA[playerid]) { if(GetPlayerVirtualWorld(playerid) != GetActorVirtualWorld(corpseid)) { SetActorVirtualWorld(corpseid, GetPlayerVirtualWorld(playerid)); } if(ValidCorpseTD[corpseid]) { Delete3DTextLabel(CorpseTD[corpseid]); CorpseTD[corpseid] = Create3DTextLabel("(( This is a dead body,\n/corpse examine for more information ))", 0xFF6666FF, x, y, z + 1, 20, GetPlayerVirtualWorld(playerid), 1); } LastX[playerid] = x; LastY[playerid] = y; LastZ[playerid] = z; LastA[playerid] = a; x += (0.2 * floatsin(-a + 180, degrees)); y += (0.2 * floatcos(-a + 180, degrees)); SetActorPos(corpseid, x, y, z + 0.8); SetActorFacingAngle(corpseid, a); } defer UpdateCorpse(playerid); } } } CMD:corpse(playerid, params[]) { if(isnull(params)) return SendSyntaxMessage(playerid, "/corpse (options: carry, drop, examine, trunk)"); if(!strcmp(params, "carry", true)) { if(IsPlayerInAnyVehicle(playerid)) return SendErrorMessage(playerid, "You have to get out of the vehicle first."); if(IsPlayerWounded(playerid)) return SendErrorMessage(playerid, "You can't do this when you're brutally wounded."); if(DraggingCorpse[playerid] != INVALID_ACTOR_ID) return SendErrorMessage(playerid, "You're already carrying a dead body."); new corpseid = GetClosestActor(playerid, 2.0); if(corpseid == INVALID_ACTOR_ID) return SendErrorMessage(playerid, "You must get closer to that dead body."); if(!IsACorpse[corpseid]) return SendErrorMessage(playerid, "That's not a corpse."); if(BeingDragged[corpseid]) return SendErrorMessage(playerid, "You can't carry that dead body."); DraggingCorpse[playerid] = corpseid; BeingDragged[corpseid] = true; defer UpdateCorpse(playerid); ApplyActorAnimation(corpseid, "PED", "DROWN", 4.1, 0, 1, 1, 1, 0); } else if(!strcmp(params, "drop", true)) { if(DraggingCorpse[playerid] == INVALID_ACTOR_ID) return SendErrorMessage(playerid, "You're not carrying a dead body."); if(IsValidActor(DraggingCorpse[playerid])) { Corpse_Drop(DraggingCorpse[playerid]); } DraggingCorpse[playerid] = INVALID_ACTOR_ID; } else if(!strcmp(params, "examine", true)) { new corpseid = GetClosestActor(playerid, 2.0); if(corpseid == INVALID_ACTOR_ID) return SendErrorMessage(playerid, "You must get closer to that dead body."); if(!IsACorpse[corpseid]) return SendErrorMessage(playerid, "That's not a corpse."); Corpse_ShowInjuries(playerid, corpseid); } else if(!strcmp(params, "trunk", true, 5)) { new option[6]; if(sscanf(params, "{s[6]}s[128]", option)) return SendSyntaxMessage(playerid, "/corpse trunk (options: place, get)"); if(!strcmp(option, "place", true)) { if(DraggingCorpse[playerid] == INVALID_ACTOR_ID || !IsValidActor(DraggingCorpse[playerid])) return SendErrorMessage(playerid, "You're not carrying a dead body."); new vehicleid = GetClosestVehicle(playerid, 2.0); if(vehicleid == INVALID_VEHICLE_ID) return SendErrorMessage(playerid, "You must get closer to that vehicle."); new corpseid = DraggingCorpse[playerid]; if(ValidCorpseTD[corpseid]) { Delete3DTextLabel(CorpseTD[corpseid]); ValidCorpseTD[corpseid] = false; } DestroyActor(corpseid); DraggingCorpse[playerid] = INVALID_ACTOR_ID; // To be continued } else if(!strcmp(option, "get", true)) { if(IsPlayerWounded(playerid)) return SendErrorMessage(playerid, "You can't do this when you're brutally wounded."); if(DraggingCorpse[playerid] != INVALID_ACTOR_ID) return SendErrorMessage(playerid, "You're already carrying a dead body."); new vehicleid = GetClosestVehicle(playerid, 2.0); if(vehicleid == INVALID_VEHICLE_ID) return SendErrorMessage(playerid, "You must get closer to that vehicle."); // To be continued } else SendSyntaxMessage(playerid, "/corpse trunk (options: place, get)"); } else SendSyntaxMessage(playerid, "/corpse (options: carry, drop, examine, trunk)"); return 1; }