Advertisement
Lorenc

CNPC 0.2.2

Jan 21st, 2012
2,610
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 13.46 KB | None | 0 0
  1. /*
  2.     *       Controllable NPC Include created by Lorenc_
  3.     *                   Version: 0.2.2a
  4.     *
  5.     *   - Credits:
  6.     *       erorcun - Ideas         RyDeR` - Mapandreas Include
  7.     *       Y_less - y_ini          Kalcor - SA-MP
  8.     *
  9.     *
  10. */
  11.  
  12. /* ** Stopping crap from duplicate ** */
  13. #if defined using_cnpc
  14.     #endinput
  15. #endif
  16. #define using_cnpc
  17.  
  18. /* ** Includes ** */
  19. #include                            <a_samp>
  20. #include                            <a_npc>
  21. #include                            <YSI/y_ini>
  22.  
  23. /* ** Configuration ** */
  24. #define MAX_CNPCS                   (100) // Don't modify if you don't know what you're doing!
  25. //#define USE_MAPANDREAS            // Comment if you are willing to use this, it's to trace the ground Z, prevents collision on the SA map.
  26.  
  27. #if defined USE_MAPANDREAS
  28.     #include                        <mapandreas>
  29. #endif
  30.  
  31.  
  32. /* ** Variables ** */
  33. enum NPC_DATA
  34. {
  35.     E_ID,               E_NAME[24],             E_SKIN,
  36.     Float: E_LOCX,      Float: E_LOCY,          Float: E_LOCZ,
  37.     bool: E_CREATED,    bool: E_CONNECTED,      bool: E_SPAWNED
  38. };
  39.  
  40. new
  41.     g_cnpcData                      [MAX_CNPCS][NPC_DATA],
  42.     g_cnpcCount                     = -1,
  43.     g_cnpcID                        [MAX_PLAYERS] = {INVALID_PLAYER_ID, ...},
  44.     g_cnpcObject                    [MAX_PLAYERS] = {INVALID_OBJECT_ID, ...},
  45.     g_cnpcTimer                     [MAX_PLAYERS],
  46.    
  47.     /* ** Hooking ** */
  48.     bool: RL_OPRS,
  49.     bool: RL_OPC,
  50.     bool: RL_OPD,
  51.     bool: RL_OPS
  52. ;
  53.  
  54.  
  55. /* ** Macro Functions ** */
  56. #define INVALID_CNPC                (Npc: 0xFFFF)
  57. #define GetCNPCTotalCount()         (g_cnpcCount)
  58. #define Convert.ToNPC(%1)           (Npc:%1)
  59. #define GetNPCPlayerID(%1)          (g_cnpcData[_:%1][E_ID])
  60. #define foreachcnpc(%1)             for(new Npc:%1; _:%1 <= g_cnpcCount; _:%1++) if(g_cnpcData[(_:%1)][E_CONNECTED])
  61. #define strmatch(%1,%2)             (!strcmp(%1,%2,false))
  62.  
  63. /* ** Forwards ** */
  64. forward LoadNPC_data(playerid, name[], value[]);
  65. forward cnpc_MoveNPC(Npc: nID, objectid);
  66.  
  67. forward OnNpcCreated(npcid);
  68. forward OnNpcFinishedMoving(npcid);
  69. forward OnNpcDestroyed(npcid);
  70. forward OnNpcConnected(npcid);
  71. forward OnNpcSpawn(npcid);
  72.  
  73. /*
  74.     native CreateCNPC(name[24], skin, Float: X, Float: Y, Float: Z)
  75.     native SetNpcMoveTo(nID, Float: X, Float: Y, Float: Z, bool: run = false)
  76.     native GetNPCPlayerID(nID)
  77.     native GetDistanceBetweenPlayerAndNPC(playerid, nID)
  78.     native GetClosestNPC(playerid)
  79.     native GetNpcIDFromPlayerID(playerid)
  80.     native StopCNPC(npcid)
  81.     native GetCNPCTotalCount()
  82.     native ReturnNpcName(npcid)
  83.     native SetNPCPos(npcid, Float: X, Float: Y, Float: Z)
  84.     native ApplyAnimationToNPC(npcid, animlib[], animname[], Float: fDelta, loop, lockx, locky, freeze, time, forcesync = 0)
  85.     native SetNPCFacingAngle(npcid, Float: Angle)
  86.     native GiveNPCWeapon(npcid, weaponid, ammo)
  87.     native ResetNPCWeapons(npcid)
  88.     native IsNpcSpawned(npcid)
  89.    
  90.     native SetPlayerFacePoint(playerid, Float: fX, Float: fY, Float: offset = 0.0)
  91.     native strmatch(const str1[], const str2[])
  92.     native strreplacechar(string[], oldchar, newchar)
  93.    
  94. */
  95.  
  96. /* ** 0.2.2 ** */
  97. #define IsNpcSpawned(%1) \
  98.     (g_cnpcData[_:%1][E_SPAWNED])
  99.  
  100. /* ** 0.2 ** */
  101. #define SetNPCPos(%1,%2,%3,%4) \
  102.     SetPlayerPos(g_cnpcData[_:%1][E_ID],%2,%3,%4)
  103.    
  104. #define SetNPCFacingAngle(%1,%2) \
  105.     SetPlayerFacingAngle(g_cnpcData[_:%1][E_ID],%2)
  106.    
  107. #define ResetNPCWeapons(%1) \
  108.     ResetPlayerWeapons(g_cnpcData[_:%1][E_ID])
  109.  
  110. #define GiveNPCWeapon(%1,%2,%3) \
  111.     GivePlayerWeapon(g_cnpcData[_:%1][E_ID],%2,%3)
  112.  
  113. stock ApplyAnimationToNPC( Npc: id, animlib[ ], animname[ ], Float: fDelta, loop, lockx, locky, freeze, time, forcesync = 0 )
  114. {
  115.     ClearAnimations(GetNPCPlayerID(id));
  116.     ApplyAnimation(GetNPCPlayerID(id), animlib, "null", 4.0, 0, 0, 0, 0, 0);
  117.     ApplyAnimation(GetNPCPlayerID(id), animlib, animname, fDelta, loop, lockx, locky, freeze, time, forcesync );
  118. }
  119.  
  120.  
  121. /* ** 0.1 ** */
  122. stock IsNPCConnected(npcid)
  123. {
  124.     if(g_cnpcData[npcid][E_CONNECTED]) return true;
  125.     return false;
  126. }
  127.  
  128. stock ReturnNpcName(npcid)
  129. {
  130.     static p_Name[24] = "Invalid NPC ID";
  131.     format(p_Name, 24, "%s", g_cnpcData[npcid][E_NAME]);
  132.     return p_Name;
  133. }
  134.  
  135. stock Npc: CreateCNPC(name[24], skin, Float: X, Float: Y, Float: Z)
  136. {
  137.     new
  138.         cID = GetFreeCNPCSlot()
  139.     ;
  140.     if(cID != 0xFFFF)
  141.     {
  142.         strreplacechar(name, ' ', '_');
  143.         if(CNPC_NameExists(name)) format(g_cnpcData[cID][E_NAME], MAX_PLAYER_NAME, "%s%d", name, cID);
  144.         else format(g_cnpcData[cID][E_NAME], MAX_PLAYER_NAME, "%s", name);
  145.         g_cnpcData[cID][E_LOCX] = X;
  146.         g_cnpcData[cID][E_LOCY] = Y;
  147.         g_cnpcData[cID][E_LOCZ] = Z;
  148.         g_cnpcData[cID][E_SKIN] = skin;
  149.         g_cnpcData[cID][E_CREATED] = true;
  150.         g_cnpcData[cID][E_CONNECTED] = false;
  151.         g_cnpcData[cID][E_SPAWNED] = false;
  152.         g_cnpcCount++;
  153.         ConnectCNPC(cID);
  154.         CallLocalFunction("OnNpcCreated", "d", _:cID);
  155.         return Npc: cID;
  156.     }
  157.     return INVALID_CNPC;
  158. }
  159.  
  160. stock DestroyCNPC(Npc: nID)
  161. {
  162.     if(!g_cnpcData[_:nID][E_CREATED])
  163.         return 0;
  164.  
  165.     if(IsPlayerConnected(g_cnpcData[_:nID][E_ID]) && IsPlayerNPC(g_cnpcData[_:nID][E_ID])) Kick(g_cnpcData[_:nID][E_ID]);
  166.     g_cnpcData[_:nID][E_ID] = INVALID_PLAYER_ID;
  167.     g_cnpcData[_:nID][E_SKIN] = 0;
  168.     g_cnpcData[_:nID][E_CREATED] = false;
  169.     g_cnpcData[_:nID][E_CONNECTED] = false;
  170.     g_cnpcData[_:nID][E_SPAWNED] = false;
  171.     g_cnpcCount--;
  172.     CallLocalFunction("OnNpcDestroyed", "d", _:nID);
  173.     return 1;
  174. }
  175.  
  176. stock SetPlayerFacePoint(playerid, Float: fX, Float: fY, Float: offset = 0.0)
  177. {
  178.     static
  179.         Float: X,
  180.         Float: Y,
  181.         Float: Z,
  182.         Float: face
  183.     ;
  184.     if(GetPlayerPos(playerid, X, Y, Z))
  185.     {
  186.         face = atan2(fY - Y, fX - X) - 90.0;
  187.         SetPlayerFacingAngle(playerid, face + offset);
  188.     }
  189. }
  190.  
  191. stock Npc: GetNpcIDFromPlayerID(playerid)
  192. {
  193.     foreachcnpc(i)
  194.     {
  195.         if(g_cnpcData[_:i][E_ID] == playerid)
  196.             return Npc:i;
  197.     }
  198.     return INVALID_CNPC;
  199. }
  200.  
  201. stock GetFreeCNPCSlot()
  202. {
  203.     for(new i; i < MAX_CNPCS; i++)
  204.     {
  205.         if(!g_cnpcData[i][E_CREATED])
  206.             return i;
  207.     }
  208.     return 0xFFFF;
  209. }
  210.  
  211. stock CNPC_NameExists(const name[24])
  212. {
  213.     for(new i; i < MAX_CNPCS; i++)
  214.     {
  215.         if(strmatch(g_cnpcData[i][E_NAME], name))
  216.             return true;
  217.     }
  218.     return false;
  219. }
  220.  
  221. stock ConnectCNPC(ID)
  222. {
  223.     if(!g_cnpcData[ID][E_CREATED])
  224.         return 0;
  225.  
  226.     new
  227.         szTmp[40],
  228.         INI: iniFile
  229.     ;
  230.     format(szTmp, 40, "CNPC/%s.ini", g_cnpcData[_:ID][E_NAME]);
  231.     iniFile = INI_Open(szTmp);
  232.    
  233.     INI_SetTag(     iniFile,    "data");
  234.     INI_WriteInt(   iniFile,    "NPCID", ID);
  235.     INI_Close(      iniFile);
  236.  
  237.     ConnectNPC(g_cnpcData[_:ID][E_NAME], "npcidle");
  238.     return 1;
  239. }
  240.  
  241. stock SetNpcMoveTo(Npc: nID, Float: X, Float: Y, Float: Z, bool: run = false)
  242. {
  243.     if(!g_cnpcData[_:nID][E_CREATED] || !g_cnpcData[_:nID][E_SPAWNED])
  244.         return 0;
  245.        
  246.     new
  247.         playerid = g_cnpcData[_:nID][E_ID],
  248.         Float: pX,
  249.         Float: pY,
  250.         Float: pZ
  251.     ;
  252.     StopCNPC(nID);
  253.     SetPlayerFacePoint(playerid, X, Y);
  254.     GetPlayerPos(playerid, pX, pY, pZ);
  255.  
  256.     g_cnpcObject[playerid] = CreateObject(1248, pX, pY, pZ - 1000, 0, 0, 0);
  257.     g_cnpcTimer[playerid]  = SetTimerEx("cnpc_MoveNPC", 75, true, "dd", _:nID, g_cnpcObject[playerid]);
  258.  
  259.     if(run)
  260.     {
  261.         ApplyAnimation(playerid, "MUSCULAR", "MuscleSprint", 4.1, 1, 1, 1, 1, 0); // Looks much better.
  262.         MoveObject(g_cnpcObject[playerid], X, Y, Z - 1000, 6.5);
  263.     }
  264.     else
  265.     {
  266.         ApplyAnimation(playerid, "PED", "WALK_player", 4.1, 1, 1, 1, 1, 0);
  267.         MoveObject(g_cnpcObject[playerid], X, Y, Z - 1000, 2.5);
  268.     }
  269.     return 1;
  270. }
  271.  
  272. public cnpc_MoveNPC(Npc: nID, objectid)
  273. {
  274.     if(!g_cnpcData[_:nID][E_CREATED] || !g_cnpcData[_:nID][E_SPAWNED])
  275.         return 0;
  276.  
  277.     new
  278.         Float: X,   Float: oX,
  279.         Float: Y,   Float: oY,
  280.         Float: Z,   Float: oZ,
  281.         Float: fS,
  282.  
  283.         playerid = g_cnpcData[_:nID][E_ID]
  284.     ;
  285.     GetObjectPos(objectid, oX, oY, oZ);
  286.     GetPlayerPos(playerid, X, Y, Z);
  287.     #if defined USE_MAPANDREAS
  288.     GetPointZPos(oX, oY, oZ);
  289.     fS = 0.8;
  290.     #else
  291.     fS = 1000.0;
  292.     #endif
  293.     if(oX == X && oY == Y && oZ + fS == Z)
  294.     {
  295.         StopCNPC(nID);
  296.         CallLocalFunction("OnNpcFinishedMoving", "d", _:nID);
  297.         return 1;
  298.     }
  299.     SetPlayerPos(playerid, oX, oY, oZ + fS);
  300.  
  301.     g_cnpcData[_:nID][E_LOCX] = oX;
  302.     g_cnpcData[_:nID][E_LOCY] = oY;
  303.     g_cnpcData[_:nID][E_LOCZ] = oZ + fS;
  304.     return 1;
  305. }
  306.  
  307. stock StopCNPC(Npc: nID)
  308. {
  309.     if(!g_cnpcData[_:nID][E_CREATED])
  310.         return 0;
  311.  
  312.     new playerid = g_cnpcData[_:nID][E_ID];
  313.     DestroyObject(g_cnpcObject[playerid]);
  314.     g_cnpcObject[playerid] = INVALID_OBJECT_ID;
  315.     KillTimer(g_cnpcTimer[playerid]);
  316.     ClearAnimations(playerid);
  317.     return 1;
  318. }
  319.  
  320.  
  321. stock GetDistanceBetweenPlayerAndNPC(playerid, Npc: nID) // Useful for chasing. made it for that purpose actually XD.
  322. {
  323.     new
  324.         Float: pX, Float: pY, Float: pZ
  325.     ;
  326.     GetPlayerPos(playerid, pX, pY, pZ);
  327.     return floatround(floatsqroot(floatpower(floatabs(floatsub(g_cnpcData[_:nID][E_LOCX], pX)), 2) + floatpower(floatabs(floatsub(g_cnpcData[_:nID][E_LOCY], pY)), 2) + floatpower(floatabs(floatsub(g_cnpcData[_:nID][E_LOCZ], pZ)), 2)));
  328. }
  329.  
  330. stock Npc: GetClosestNPC(playerid) // This function contributes to the above, as said, to chase a player :D
  331. {
  332.     new
  333.         Float: fDistance,
  334.         Float: fHighest,
  335.         Npc: iPlayer = INVALID_CNPC
  336.     ;
  337.     foreachcnpc(npcid)
  338.     {
  339.         fDistance = GetDistanceBetweenPlayerAndNPC(playerid, npcid);
  340.         if(fDistance > fHighest) fHighest = fDistance, iPlayer = Npc: npcid;
  341.     }
  342.     return iPlayer;
  343. }
  344.  
  345. stock strreplacechar(string[], oldchar, newchar) // I assume it's by some [DRuG] member.
  346. {
  347.     new matches;
  348.     if(ispacked(string)) {
  349.         if(newchar == '\0') {
  350.             for(new i; string{i} != '\0'; i++) {
  351.                 if(string{i} == oldchar) {
  352.                     strdel(string, i, i + 1);
  353.                     matches++;
  354.                 }
  355.             }
  356.         } else {
  357.             for(new i; string{i} != '\0'; i++) {
  358.                 if(string{i} == oldchar) {
  359.                     string{i} = newchar;
  360.                     matches++;
  361.                 }
  362.             }
  363.         }
  364.     } else {
  365.         if(newchar == '\0') {
  366.             for(new i; string[i] != '\0'; i++) {
  367.                 if(string[i] == oldchar) {
  368.                     strdel(string, i, i + 1);
  369.                     matches++;
  370.                 }
  371.             }
  372.         } else {
  373.             for(new i; string[i] != '\0'; i++) {
  374.                 if(string[i] == oldchar) {
  375.                     string[i] = newchar;
  376.                     matches++;
  377.                 }
  378.             }
  379.         }
  380.     }
  381.     return matches;
  382. }
  383.  
  384. public LoadNPC_data(playerid, name[], value[]) {
  385.     if(strmatch(name, "NPCID"))             g_cnpcID[playerid] = strval(value);
  386. }
  387.  
  388. public OnPlayerRequestSpawn(playerid)
  389. {
  390.     if(IsPlayerNPC(playerid))
  391.     {
  392.         new
  393.             name[40]
  394.         ;
  395.         GetPlayerName(playerid, name, 24);
  396.         format(name, 40, "CNPC/%s.ini", name);
  397.         if(fexist(name))
  398.         {
  399.             INI_ParseFile(name, "LoadNPC_%s", .bExtra = true, .extra = playerid);
  400.             new npcid = g_cnpcID[playerid];
  401.             g_cnpcData[npcid][E_ID] = playerid;
  402.             g_cnpcData[npcid][E_CONNECTED] = true;
  403.             SetSpawnInfo(playerid, NO_TEAM, g_cnpcData[npcid][E_SKIN], g_cnpcData[npcid][E_LOCX], g_cnpcData[npcid][E_LOCY], g_cnpcData[npcid][E_LOCZ], 0, -1, -1, -1, -1, -1, -1);
  404.             CallLocalFunction("OnNpcConnected", "d", _:npcid);
  405.         }
  406.         return 1;
  407.     }
  408.     return ( RL_OPRS ) ? CallLocalFunction("RL_OnPlayerRequestSpawn", "d", playerid) : 1;
  409. }
  410.  
  411. #if defined _ALS_OnPlayerRequestSpawn
  412.     #undef OnPlayerRequestSpawn
  413. #else
  414.     #define _ALS_OnPlayerRequestSpawn
  415. #endif
  416. #define OnPlayerRequestSpawn RL_OnPlayerRequestSpawn
  417. forward RL_OnPlayerRequestSpawn( playerid );
  418.  
  419. public OnPlayerConnect(playerid)
  420. {
  421.     if(IsPlayerNPC(playerid))
  422.         return 1;
  423.        
  424.     return ( RL_OPC ) ? CallLocalFunction( "RL_OnPlayerConnect", "d", playerid ) : 1;
  425. }
  426.  
  427. #if defined _ALS_OnPlayerConnect
  428.     #undef OnPlayerConnect
  429. #else
  430.     #define _ALS_OnPlayerConnect
  431. #endif
  432. #define OnPlayerConnect RL_OnPlayerConnect
  433. forward RL_OnPlayerConnect( playerid );
  434.  
  435. public OnPlayerDisconnect(playerid, reason)
  436. {
  437.     if(IsPlayerNPC(playerid))
  438.         return DestroyCNPC(GetNpcIDFromPlayerID(playerid)), 1;
  439.    
  440.     return ( RL_OPD ) ? CallLocalFunction( "RL_OnPlayerDisconnect", "dd", playerid, reason ) : 1;
  441. }
  442.  
  443. #if defined _ALS_OnPlayerDisconnect
  444.     #undef OnPlayerDisconnect
  445. #else
  446.     #define _ALS_OnPlayerDisconnect
  447. #endif
  448. #define OnPlayerDisconnect RL_OnPlayerDisconnect
  449. forward RL_OnPlayerDisconnect( playerid, reason );
  450.  
  451. public OnPlayerSpawn(playerid)
  452. {
  453.     if( IsPlayerNPC( playerid ) )
  454.     {
  455.         new
  456.             npcid = _:GetNpcIDFromPlayerID(playerid)
  457.         ;
  458.         if( npcid != _:INVALID_CNPC )
  459.         {
  460.             g_cnpcData[npcid][E_SPAWNED] = true;
  461.             CallLocalFunction("OnNpcSpawn", "d", npcid);
  462.             SetNPCPos( npcid, g_cnpcData[ npcid ] [ E_LOCX ],g_cnpcData[ npcid ] [ E_LOCY ],g_cnpcData[ npcid ] [ E_LOCZ ] + 1);
  463.         }
  464.     }
  465.     return ( RL_OPS ) ? CallLocalFunction( "RL_OnPlayerSpawn", "d", playerid ) : 1;
  466. }
  467.  
  468. #if defined _ALS_OnPlayerSpawn
  469.     #undef OnPlayerSpawn
  470. #else
  471.     #define _ALS_OnPlayerSpawn
  472. #endif
  473. #define OnPlayerSpawn RL_OnPlayerSpawn
  474. forward RL_OnPlayerSpawn( playerid );
  475.  
  476. #if !defined FILTERSCRIPT
  477.     public OnGameModeInit()
  478.     {
  479.         RL_OPRS = ( funcidx( "RL_OnPlayerRequestSpawn" ) != -1 );
  480.         RL_OPC = ( funcidx( "RL_OnPlayerConnect" ) != -1 );
  481.         RL_OPD = ( funcidx( "RL_OnPlayerDisconnect" ) != -1 );
  482.         RL_OPS = ( funcidx( "RL_OnPlayerSpawn" ) != -1 );
  483.         return ( funcidx( "RL_OnGameModeInit" ) != -1 ) ? CallLocalFunction( "RL_OnGameModeInit", "" ) : 1;
  484.     }  
  485.     #if defined _ALS_OnGameModeInit
  486.         #undef OnGameModeInit
  487.     #else
  488.         #define _ALS_OnGameModeInit
  489.     #endif
  490.     #define OnGameModeInit RL_OnGameModeInit
  491.     forward RL_OnGameModeInit();
  492. #else
  493.     public OnFilterScriptInit()
  494.     {
  495.         RL_OPRS = ( funcidx( "RL_OnPlayerRequestSpawn" ) != -1 );
  496.         RL_OPC = ( funcidx( "RL_OnPlayerConnect" ) != -1 );
  497.         RL_OPD = ( funcidx( "RL_OnPlayerDisconnect" ) != -1 );
  498.         RL_OPS = ( funcidx( "RL_OnPlayerSpawn" ) != -1 );
  499.         return ( funcidx( "RL_OnFilterScriptInit" ) != -1 ) ? CallLocalFunction( "RL_OnFilterScriptInit", "" ) : 1;
  500.     }  
  501.     #if defined _ALS_OnFilterScriptInit
  502.         #undef OnFilterScriptInit
  503.     #else
  504.         #define _ALS_OnFilterScriptInit
  505.     #endif
  506.     #define OnFilterScriptInit RL_OnFilterScriptInit
  507.     forward RL_OnFilterScriptInit();
  508. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement