Admigo

Extended Actor Functions Update 08.04.2016

Apr 8th, 2016
1,599
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 13.48 KB | None | 0 0
  1. /*
  2.  *  Extended actor functions by Emmet.
  3.  *  Updated by Admigo
  4.  *
  5.  *  Features:
  6.  *    Many useful functions for more actor control
  7.  *    Automatically preloads animations for an actor
  8.  *    Damage is automatically deducted
  9.  *    Attach 3D labels to an actor
  10.  *    Lots more!
  11.  *
  12.  *  Update 08.04.2016
  13.  *  - Added SetActorName(actorid, name[]);
  14.  *  - Added GetActorName(actorid);
  15.  *  - Added ToggleActorName(actorid, toggle);
  16.  *  - Added SetActorChatBubble(actorid, text[], color, Float:drawdistance, expiretime);
  17.  *
  18.  *
  19.  *  Creation date: May 8, 2015
  20. */
  21.  
  22.  
  23.  
  24. #define MAX_ACTOR_NAME 24
  25. #define ACTOR_NAME_DRAW_DISTANCE (10.0)
  26.  
  27.  
  28. // Resynchronize an actor.
  29. forward ResyncActor(actorid);
  30. // Respawns an actor.
  31. forward RespawnActor(actorid);
  32. // Checks if the actor is dead.
  33. forward IsActorDead(actorid);
  34. // Sets an actor's respawn time (after death).
  35. forward SetActorRespawnTime(actorid, time);
  36. // Checks if a player is in range of an actor.
  37. forward IsPlayerInRangeOfActor(playerid, actorid, Float:radius = 5.0);
  38. // Attaches a 3D text label to an actor.
  39. forward Text3D:Attach3DTextLabelToActor(actorid, text[], color, Float:fOffsetX, Float:fOffsetY, Float:fOffsetZ, Float:distance = 10.0, worldid = 0, testlos = 0);
  40.  
  41. // Called when an actor dies.
  42. forward OnActorDeath(actorid, killerid, reason);
  43. // Called when an actor spawns.
  44. forward OnActorSpawn(actorid);
  45. // Called when a player aims at an actor.
  46. forward OnPlayerTargetActor(playerid, newtarget, oldtarget);
  47.  
  48. // List of animation libraries used for preloading.
  49. static s_AnimationLibraries[][] = {
  50.     !"AIRPORT",    !"ATTRACTORS",   !"BAR",         !"BASEBALL",
  51.     !"BD_FIRE",    !"BEACH",        !"BENCHPRESS",  !"BF_INJECTION",
  52.     !"BIKED",      !"BIKEH",        !"BIKELEAP",    !"BIKES",
  53.     !"BIKEV",      !"BIKE_DBZ",     !"BMX",         !"BOMBER",
  54.     !"BOX",        !"BSKTBALL",     !"BUDDY",       !"BUS",
  55.     !"CAMERA",     !"CAR",          !"CARRY",       !"CAR_CHAT",
  56.     !"CASINO",     !"CHAINSAW",     !"CHOPPA",      !"CLOTHES",
  57.     !"COACH",      !"COLT45",       !"COP_AMBIENT", !"COP_DVBYZ",
  58.     !"CRACK",      !"CRIB",         !"DAM_JUMP",     !"DANCING",
  59.     !"DEALER",     !"DILDO",        !"DODGE",        !"DOZER",
  60.     !"DRIVEBYS",   !"FAT",          !"FIGHT_B",      !"FIGHT_C",
  61.     !"FIGHT_D",    !"FIGHT_E",      !"FINALE",       !"FINALE2",
  62.     !"FLAME",      !"FLOWERS",      !"FOOD",         !"FREEWEIGHTS",
  63.     !"GANGS",      !"GHANDS",       !"GHETTO_DB",    !"GOGGLES",
  64.     !"GRAFFITI",   !"GRAVEYARD",    !"GRENADE",      !"GYMNASIUM",
  65.     !"HAIRCUTS",   !"HEIST9",       !"INT_HOUSE",    !"INT_OFFICE",
  66.     !"INT_SHOP",   !"JST_BUISNESS", !"KART",         !"KISSING",
  67.     !"KNIFE",      !"LAPDAN1",      !"LAPDAN2",      !"LAPDAN3",
  68.     !"LOWRIDER",   !"MD_CHASE",     !"MD_END",       !"MEDIC",
  69.     !"MISC",       !"MTB",          !"MUSCULAR",     !"NEVADA",
  70.     !"ON_LOOKERS", !"OTB",          !"PARACHUTE",    !"PARK",
  71.     !"PAULNMAC",   !"PED",          !"PLAYER_DVBYS", !"PLAYIDLES",
  72.     !"POLICE",     !"POOL",         !"POOR",         !"PYTHON",
  73.     !"QUAD",       !"QUAD_DBZ",     !"RAPPING",      !"RIFLE",
  74.     !"RIOT",       !"ROB_BANK",     !"ROCKET",       !"RUSTLER",
  75.     !"RYDER",      !"SCRATCHING",   !"SHAMAL",       !"SHOP",
  76.     !"SHOTGUN",    !"SILENCED",     !"SKATE",        !"SMOKING",
  77.     !"SNIPER",     !"SPRAYCAN",     !"STRIP",        !"SUNBATHE",
  78.     !"SWAT",       !"SWEET",        !"SWIM",         !"SWORD",
  79.     !"TANK",       !"TATTOOS",      !"TEC",          !"TRAIN",
  80.     !"TRUCK",      !"UZI",          !"VAN",          !"VENDING",
  81.     !"VORTEX",     !"WAYFARER",     !"WEAPONS",      !"WUZI",
  82.     !"WOP",        !"GFUNK",        !"RUNNINGMAN"
  83. };
  84.  
  85. static s_ActorRespawnTimer[MAX_ACTORS] = {-1, ...};
  86. static s_ActorChatBubbleTimer[MAX_ACTORS] = {-1, ...};
  87. static s_TargetActor[MAX_PLAYERS] = {INVALID_ACTOR_ID, ...};
  88. static s_3DTextActorID[MAX_3DTEXT_GLOBAL] = {INVALID_ACTOR_ID, ...};
  89.  
  90. enum Actor_data
  91. {
  92.     a_Name[MAX_ACTOR_NAME],
  93.     a_Color,
  94.     Text3D:a_NameTag,
  95.     Text3D:a_ChatBubble,
  96.     bool:a_NameTagCreated,
  97.     bool:a_ChatBubbleCreated,
  98.     bool:a_ShowNameTag
  99. }
  100. new ActorInfo[MAX_ACTORS][Actor_data];
  101.  
  102.  
  103. stock static PreloadActorAnimations(actorid)
  104. {
  105.     for(new i = 0; i < sizeof(s_AnimationLibraries); i ++)
  106.     {
  107.         ApplyActorAnimation(actorid, s_AnimationLibraries[i], "null", 0.0, 0, 0, 0, 0, 0);
  108.     }
  109. }
  110.  
  111. stock ResyncActor(actorid)
  112. {
  113.     if(IsValidActor(actorid))
  114.     {
  115.         new
  116.             Float:x,
  117.             Float:y,
  118.             Float:z,
  119.             worldid = GetActorVirtualWorld(actorid);
  120.            
  121.         // Get the actor's position.
  122.         GetActorPos(actorid, x, y, z);
  123.         // Set their position and world to some arbitrary values.
  124.         SetActorPos(actorid, 1000.0, -2000.0, 500.0);
  125.         SetActorVirtualWorld(actorid, random(cellmax));
  126.         // We need a timer to defer the actions. Doing it right away doesn't seem to work.
  127.         SetTimerEx("RestoreActor", 850, 0, "iifff", actorid, worldid, x, y, z);
  128.         return 1;
  129.     }
  130.     return 0;
  131. }
  132.  
  133. forward RestoreActor(actorid, worldid, Float:x, Float:y, Float:z);
  134. public RestoreActor(actorid, worldid, Float:x, Float:y, Float:z)
  135. {
  136.     SetActorVirtualWorld(actorid, worldid);
  137.     SetActorPos(actorid, x, y, z);
  138.     return 1;
  139. }
  140.  
  141. // That's right, a public function. See "SetActorRespawnTime" for details.
  142. forward RespawnActor(actorid);
  143. public RespawnActor(actorid)
  144. {
  145.     if(IsValidActor(actorid))
  146.     {
  147.         // Reset the timer variable if set.
  148.         s_ActorRespawnTimer[actorid] = -1;
  149.         s_ActorChatBubbleTimer[actorid] = -1;
  150.         // Restore the actor's health.
  151.         SetActorHealth(actorid, 100.0);
  152.         // Clear the death animation.
  153.         ClearActorAnimations(actorid);
  154.         // Resync the actor.
  155.         ResyncActor(actorid);
  156.         // Call "OnActorSpawn".
  157.         CallLocalFunction("OnActorSpawn", "i", actorid);
  158.         return 1;
  159.     }
  160.     return 0;
  161. }
  162.  
  163. forward DestroyChatBubble(actorid);
  164. public DestroyChatBubble(actorid)
  165. {
  166.     if(IsValidActor(actorid))
  167.     {
  168.         // Reset the variables.
  169.         ActorInfo[actorid][a_ChatBubbleCreated] = false;
  170.         // Delete the 3D Text Label
  171.         Delete3DTextLabel(ActorInfo[actorid][a_ChatBubble]);
  172.         // Reset the timer variable if set.
  173.         s_ActorChatBubbleTimer[actorid] = -1;
  174.         //return 1;
  175.     }
  176.     return 1;
  177. }
  178.  
  179. stock IsActorDead(actorid)
  180. {
  181.     if(IsValidActor(actorid))
  182.     {
  183.         new
  184.             Float:health;
  185.    
  186.         // Get the actor's health.
  187.         GetActorHealth(actorid, health);
  188.         return (health <= 0.0);
  189.     }
  190.     return 0;
  191. }
  192.  
  193. stock SetActorRespawnTime(actorid, time)
  194. {
  195.     if(IsValidActor(actorid))
  196.     {
  197.         if(s_ActorRespawnTimer[actorid] != -1)
  198.         {
  199.             // Kill any previously created timer.
  200.             KillTimer(s_ActorRespawnTimer[actorid]);
  201.         }
  202.         s_ActorRespawnTimer[actorid] = SetTimerEx("RespawnActor", time, 0, "i", actorid);
  203.         return 1;
  204.     }
  205.     return 0;
  206. }
  207.  
  208. stock IsPlayerInRangeOfActor(playerid, actorid, Float:radius = 5.0)
  209. {
  210.     new
  211.         Float:x,
  212.         Float:y,
  213.         Float:z;
  214.  
  215.     if (GetActorPos(actorid, x, y, z))
  216.     {
  217.         return IsPlayerInRangeOfPoint(playerid, radius, x, y, z) && GetPlayerVirtualWorld(playerid) == GetActorVirtualWorld(actorid);
  218.     }
  219.     return 0;
  220. }
  221.  
  222. stock Text3D:Attach3DTextLabelToActor(actorid, text[], color, Float:fOffsetX, Float:fOffsetY, Float:fOffsetZ, Float:distance = 10.0, worldid = 0, testlos = 0)
  223. {
  224.     new Text3D:textid = Text3D:INVALID_3DTEXT_ID;
  225.  
  226.     if(IsValidActor(actorid))
  227.     {
  228.         new
  229.             Float:x,
  230.             Float:y,
  231.             Float:z;
  232.  
  233.         GetActorPos(actorid, x, y, z);
  234.        
  235.         textid = Create3DTextLabel(text, color, x + fOffsetX, y + fOffsetY, (z + 0.8) + fOffsetZ, distance, worldid, testlos);
  236.        
  237.         if(textid != Text3D:INVALID_3DTEXT_ID)
  238.         {
  239.             s_3DTextActorID[_:textid] = actorid;
  240.         }
  241.     }
  242.     return textid;
  243. }
  244.  
  245. stock SetActorName(actorid, name[])
  246. {
  247.     if(IsValidActor(actorid))
  248.     {
  249.         new
  250.             Float:x,
  251.             Float:y,
  252.             Float:z,
  253.             worldid = GetActorVirtualWorld(actorid);
  254.         GetActorPos(actorid, x, y, z);
  255.         format(ActorInfo[actorid][a_Name],MAX_ACTOR_NAME,"%s",name);
  256.         ActorInfo[actorid][a_ShowNameTag] = true;
  257.         if(ActorInfo[actorid][a_NameTagCreated] == false)
  258.         {
  259.             ActorInfo[actorid][a_NameTag] = Create3DTextLabel(ActorInfo[actorid][a_Name], ActorInfo[actorid][a_Color], x, y, (z + 1.0), ACTOR_NAME_DRAW_DISTANCE, worldid, 0);
  260.             ActorInfo[actorid][a_NameTagCreated] = true;
  261.         }
  262.         else
  263.         {
  264.             Update3DTextLabelText(ActorInfo[actorid][a_NameTag],ActorInfo[actorid][a_Color],ActorInfo[actorid][a_Name]);
  265.         }
  266.     }
  267.     return 1;
  268. }
  269.  
  270. stock GetActorName(actorid)
  271. {
  272.     new aname[MAX_ACTOR_NAME];
  273.     if(IsValidActor(actorid))
  274.     {
  275.         format(aname, sizeof(aname), "%s",ActorInfo[actorid][a_Name]);
  276.         return aname;
  277.     }
  278.     return aname;
  279. }
  280.  
  281. stock SetActorColor(actorid, color)
  282. {
  283.     ActorInfo[actorid][a_Color]=color;
  284.     if(ActorInfo[actorid][a_NameTagCreated] == true)
  285.     {
  286.         Update3DTextLabelText(ActorInfo[actorid][a_NameTag],ActorInfo[actorid][a_Color],ActorInfo[actorid][a_Name]);
  287.     }
  288.     return 1;
  289. }
  290.  
  291. stock ToggleActorName(actorid,bool:toggle)
  292. {
  293.     ActorInfo[actorid][a_ShowNameTag] = toggle;
  294.     if(ActorInfo[actorid][a_ShowNameTag] == true)
  295.     {
  296.         SetActorName(actorid, ActorInfo[actorid][a_Name]);
  297.     }
  298.     else
  299.     {
  300.         Delete3DTextLabel(ActorInfo[actorid][a_NameTag]);
  301.         ActorInfo[actorid][a_NameTagCreated] = false;
  302.     }
  303.     return 1;
  304. }
  305.  
  306. stock SetActorChatBubble(actorid, text[], color, Float:drawdistance, expiretime)
  307. {
  308.     if(IsValidActor(actorid))
  309.     {
  310.         new
  311.             Float:x,
  312.             Float:y,
  313.             Float:z,
  314.             worldid = GetActorVirtualWorld(actorid);
  315.  
  316.         GetActorPos(actorid, x, y, z);
  317.         if(ActorInfo[actorid][a_ChatBubbleCreated] == false)
  318.         {
  319.             ActorInfo[actorid][a_ChatBubble] = Create3DTextLabel(text, color, x, y, (z + 1.2), drawdistance, worldid, 0);
  320.             ActorInfo[actorid][a_ChatBubbleCreated] = true;
  321.         }
  322.         else
  323.         {
  324.             Update3DTextLabelText(ActorInfo[actorid][a_ChatBubble],color,text);
  325.         }
  326.         s_ActorChatBubbleTimer[actorid] = SetTimerEx("DestroyChatBubble", expiretime, 0, "i", actorid);
  327.         return 1;
  328.     }
  329.     return 1;
  330. }
  331.  
  332. stock AC_CreateActor(modelid, Float:x, Float:y, Float:z, Float:rotation)
  333. {
  334.     new
  335.         actorid = INVALID_ACTOR_ID;
  336.  
  337.     if(0 <= modelid <= 311)
  338.     {
  339.         actorid = CreateActor(modelid, x, y, z, rotation);
  340.  
  341.         if (actorid != INVALID_ACTOR_ID)
  342.         {
  343.             // Reset the timer variable.
  344.             s_ActorRespawnTimer[actorid] = -1;
  345.             // Set Actor color to white
  346.             ActorInfo[actorid][a_Color]= 0xFFFFFFFF;
  347.             // Preload their animations.
  348.             PreloadActorAnimations(actorid);
  349.             // Let them know that they've spawned.
  350.             CallLocalFunction("OnActorSpawn", "i", actorid);
  351.         }
  352.     }
  353.     return actorid;
  354. }
  355.  
  356. stock AC_DestroyActor(actorid)
  357. {
  358.     if(IsValidActor(actorid))
  359.     {
  360.         for(new i = 0; i < MAX_3DTEXT_GLOBAL; i ++)
  361.         {
  362.             if(s_3DTextActorID[i] == actorid)
  363.             {
  364.                 // Destroy the 3D text label.
  365.                 Delete3DTextLabel(Text3D:i);
  366.                 Delete3DTextLabel(ActorInfo[actorid][a_NameTag]);
  367.                 Delete3DTextLabel(ActorInfo[actorid][a_ChatBubble]);
  368.                 // Reset the variables.
  369.                 s_3DTextActorID[i] = INVALID_ACTOR_ID;
  370.                 ActorInfo[actorid][a_NameTagCreated] = false;
  371.                 ActorInfo[actorid][a_ChatBubbleCreated] = false;
  372.                 ActorInfo[actorid][a_Color]= 0xFFFFFFFF;
  373.             }
  374.         }
  375.         return DestroyActor(actorid);
  376.     }
  377.     return 0;
  378. }
  379.  
  380. stock AC_Delete3DTextLabel(Text3D:textid)
  381. {
  382.     if(textid != Text3D:INVALID_3DTEXT_ID)
  383.     {
  384.         // Reset the variable.
  385.         s_3DTextActorID[_:textid] = INVALID_ACTOR_ID;
  386.         return Delete3DTextLabel(textid);
  387.     }
  388.     return 0;
  389. }
  390.  
  391. public OnPlayerUpdate(playerid)
  392. {
  393.     new target_actor = GetPlayerTargetActor(playerid);
  394.    
  395.     if (s_TargetActor[playerid] != target_actor)
  396.     {
  397.         CallLocalFunction("OnPlayerTargetActor", "iii", playerid, target_actor, s_TargetActor[playerid]);
  398.    
  399.         s_TargetActor[playerid] = target_actor;
  400.     }
  401.     #if defined AC_OnPlayerUpdate
  402.         return AC_OnPlayerUpdate(playerid);
  403.     #else
  404.         return 1;
  405.     #endif
  406. }
  407.  
  408. public OnPlayerGiveDamageActor(playerid, damaged_actorid, Float:amount, weaponid, bodypart)
  409. {
  410.     // Sanity checks for safety. Players can easily manipulate this data.
  411.     if(!IsValidActor(damaged_actorid) || (!(0 <= amount <= 500.0)) || (!(0 <= weaponid <= 42)))
  412.     {
  413.         return 0;
  414.     }
  415.     else if(!IsActorInvulnerable(damaged_actorid))
  416.     {
  417.         new
  418.             Float:health;
  419.            
  420.         // Deduct the damage from the actor, since it has to be done manually.
  421.         GetActorHealth(damaged_actorid, health);       
  422.         SetActorHealth(damaged_actorid, health - amount);
  423.        
  424.         if(health - amount < 1.0)
  425.         {
  426.             // There's a bug where animations aren't cleared when an actor dies.
  427.             ClearActorAnimations(damaged_actorid);
  428.             // Delete the chat bubble because the actor is dead.
  429.             Delete3DTextLabel(ActorInfo[damaged_actorid][a_ChatBubble]);
  430.             // Call the function to let them know they're dead.
  431.             CallLocalFunction("OnActorDeath", "iii", damaged_actorid, playerid, weaponid);
  432.         }
  433.     }
  434.     #if defined AC_OnPlayerGiveDamageActor
  435.         return AC_OnPlayerGiveDamageActor(playerid, damaged_actorid, amount, weaponid, bodypart);
  436.     #else
  437.         return 1;
  438.     #endif
  439. }
  440.  
  441. #if defined _ALS_CreateActor
  442.     #undef CreateActor
  443. #else
  444.     #define _ALS_CreateActor
  445. #endif
  446.  
  447. #define CreateActor AC_CreateActor
  448.  
  449. #if defined _ALS_DestroyActor
  450.     #undef DestroyActor
  451. #else
  452.     #define _ALS_DestroyActor
  453. #endif
  454.  
  455. #define DestroyActor AC_DestroyActor
  456.  
  457. #if defined _ALS_Delete3DTextLabel
  458.     #undef Delete3DTextLabel
  459. #else
  460.     #define _ALS_Delete3DTextLabel
  461. #endif
  462.  
  463. #define Delete3DTextLabel AC_Delete3DTextLabel
  464.  
  465. #if defined _ALS_OnPlayerUpdate
  466.     #undef OnPlayerUpdate
  467. #else
  468.     #define _ALS_OnPlayerUpdate
  469. #endif
  470.  
  471. #define OnPlayerUpdate AC_OnPlayerUpdate
  472.  
  473. #if defined AC_OnPlayerUpdate
  474.     forward AC_OnPlayerUpdate(playerid);
  475. #endif
  476.  
  477. #if defined _ALS_OnPlayerGiveDamageActor
  478.     #undef OnPlayerGiveDamageActor
  479. #else
  480.     #define _ALS_OnPlayerGiveDamageActor
  481. #endif
  482.  
  483. #define OnPlayerGiveDamageActor AC_OnPlayerGiveDamageActor
  484.  
  485. #if defined AC_OnPlayerGiveDamageActor
  486.     forward AC_OnPlayerGiveDamageActor(playerid, damaged_actorid, Float:amount, weaponid, bodypart);
  487. #endif
Add Comment
Please, Sign In to add comment