SAMP Gitlab CI Test
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

835 lines
23 KiB

  1. //-------------------------------------------------------
  2. //
  3. // GRAND LARCENY Property creation and management script
  4. //
  5. // by damospiderman 2008
  6. //
  7. //-------------------------------------------------------
  8. #include <a_samp>
  9. #include "../include/gl_common.inc"
  10. #define FILTERSCRIPT
  11. //#define USE_SQLITE
  12. #define PROP_VW (10000)
  13. #define MAX_INTERIORS (146)
  14. #define MAX_PROPERTIES (1000)
  15. #define PROPERTY_FOLDER "properties" // Location of properties file
  16. #define PROPERTY_UNIQID_FILE "properties/uniqId.txt" // Location of Uniq Interior Info
  17. #define DB_PROPERTIES "properties/dbProperties.db" // Location of the properties Database
  18. #define MAX_TYPES (5)
  19. #define TYPE_EMPTY (0)
  20. #define TYPE_HOUSE (1)
  21. #define TYPE_BUSINESS (2)
  22. #define TYPE_BANK (3)
  23. #define TYPE_COP (4)
  24. enum // Property Type Enum
  25. E_P_TYPES {
  26. tIcon,
  27. tName[32]
  28. }
  29. enum // Uniq Interiors Enum
  30. E_INTERIORS {
  31. inIntID,
  32. Float:inExitX,
  33. Float:inExitY,
  34. Float:inExitZ,
  35. Float:inExitA,
  36. inName[64]
  37. };
  38. enum // Properties Enum
  39. E_PROPERTIES {
  40. eInterior,
  41. eType,
  42. Float:eEntX,
  43. Float:eEntY,
  44. Float:eEntZ,
  45. Float:eEntA,
  46. eUniqIntId,
  47. eOwner,
  48. ePrice,
  49. ePname[64]
  50. };
  51. // [ uniq property id ]
  52. new unid;
  53. // [ Array of all the property interior info ]
  54. new interiorInfo[MAX_INTERIORS][E_INTERIORS];
  55. // [ Pickup array with property id assigned via array slot ( pickupid ) ]
  56. new propPickups[MAX_PROPERTIES] = {-1};
  57. // [ Handles for 3D text displayed at property entrances ]
  58. new Text3D:propTextInfo[MAX_PROPERTIES];
  59. // [ Mass array of all the properties and info about them ]
  60. new properties[MAX_PROPERTIES][E_PROPERTIES];
  61. // [ The last pickup the player went through so they can do /enter command ]
  62. new lastPickup[MAX_PLAYERS] = {-1};
  63. // [ Current property Unique Interior the player is in.. defaults to -1 when not in any property ]
  64. new currentInt[MAX_PLAYERS] = {-1};
  65. // [ Player Position array to store the last place the player was before /view command so they can be teleported back ]
  66. new Float:plPos[MAX_PLAYERS][3];
  67. // [ Players actual interior id used for /view /return command ]
  68. new plInt[MAX_PLAYERS];
  69. // [ Array of property type iconid's and strings for property type ]
  70. new propIcons[MAX_TYPES][E_P_TYPES] = {
  71. { 0, "" }, // TYPE_EMPTY ( not used )
  72. { 1273, "House" }, // TYPE_HOUSE green house icon
  73. { 1272, "Business" }, // TYPE_BUSINESS blue house icon
  74. { 1274, "Bank" }, // TYPE_BANK dollar sign icon
  75. { 1247, "Police Station" } // TYPE_COP Bribe Star 1247
  76. };
  77. new propFile[MAX_TYPES][64] = {
  78. { "blank" },
  79. { "properties/houses.txt" },
  80. { "properties/businesses.txt" },
  81. { "properties/banks.txt" },
  82. { "properties/police.txt" }
  83. };
  84. // Keep track of what properties we've sent an /enter notification for
  85. new gLastPropertyEnterNotification[MAX_PLAYERS];
  86. /********************************
  87. * Interior Info Functions *
  88. ********************************/
  89. stock Float:GetInteriorExit( id, &Float:x, &Float:y, &Float:z ){
  90. if( id > MAX_INTERIORS ) return 0.0;
  91. else {
  92. x = interiorInfo[id][inExitX];
  93. y = interiorInfo[id][inExitY];
  94. z = interiorInfo[id][inExitZ];
  95. return interiorInfo[id][inExitA];
  96. }
  97. }
  98. // Gets interior exit info from uniq Interior Id. Returns InteriorId or -1 if interior doesn't exist
  99. stock GetInteriorExitInfo( uniqIntId, &Float:exitX, &Float:exitY, &Float:exitZ, &Float:exitA ){
  100. if( uniqIntId < MAX_INTERIORS ){
  101. exitX = interiorInfo[uniqIntId][inExitX];
  102. exitY = interiorInfo[uniqIntId][inExitY];
  103. exitZ = interiorInfo[uniqIntId][inExitZ];
  104. exitA = interiorInfo[uniqIntId][inExitA];
  105. return interiorInfo[uniqIntId][inIntID];
  106. }
  107. return -1;
  108. }
  109. stock GetInteriorIntID( id ){ // Gets the interior id of a uniq Interior Id :S
  110. if( id > MAX_INTERIORS ) return -1;
  111. else return interiorInfo[id][inIntID];
  112. }
  113. stock GetInteriorName( id )
  114. {
  115. new tmp[64];
  116. if( id > MAX_PROPERTIES ) return tmp;
  117. else {
  118. format( tmp, 64, "%s", interiorInfo[id][inName] );
  119. return tmp;
  120. }
  121. }
  122. /********************************************************
  123. ********************************************************/
  124. /********************************
  125. * Property Functions *
  126. ********************************/
  127. stock Float:GetPropertyEntrance( id, &Float:x, &Float:y, &Float:z ){
  128. if( id > MAX_PROPERTIES ) return 0.0;
  129. x = properties[id][eEntX];
  130. y = properties[id][eEntY];
  131. z = properties[id][eEntZ];
  132. return properties[id][eEntA];
  133. }
  134. stock Float:GetPropertyExit( id, &Float:x, &Float:y, &Float:z ){
  135. if( id > MAX_PROPERTIES ) return 0.0;
  136. return GetInteriorExit( properties[id][eUniqIntId], x, y, z );
  137. }
  138. stock GetPropertyInteriorFileId( id ){
  139. if( id > MAX_PROPERTIES ) return 0;
  140. else return properties[id][eUniqIntId];
  141. }
  142. stock GetPropertyInteriorId( id ){
  143. if( id > MAX_PROPERTIES ) return 0;
  144. else return GetInteriorIntID( properties[id][eUniqIntId] );
  145. }
  146. stock GetPropertyType( id ){
  147. if( id > MAX_PROPERTIES ) return 0;
  148. else return properties[id][eType];
  149. }
  150. stock GetPropertyOwner( id ){
  151. if( id > MAX_PROPERTIES ) return -1;
  152. else return properties[id][eOwner];
  153. }
  154. stock GetPropertyPrice( id ){
  155. if( id > MAX_PROPERTIES ) return -1;
  156. else return properties[id][ePrice];
  157. }
  158. stock GetPropertyName( id ){
  159. new tmp[64];
  160. if( id > MAX_PROPERTIES ) return tmp;
  161. else {
  162. format( tmp, 64, "%s", properties[id][ePname] );
  163. return tmp;
  164. }
  165. }
  166. /********************************************************
  167. ********************************************************/
  168. /********************************
  169. * Database Functions *
  170. ********************************/
  171. stock Float:dbGetPropertyEntrance( database[], uniqId, &Float:x, &Float:y, &Float:z ){
  172. new
  173. DB:prop,
  174. DBResult:query_result,
  175. query[128],
  176. num;
  177. prop = db_open( database );
  178. format( query, 128,"SELECT entX, entY, enZ, entA FROM properties WHERE id = %d LIMIT 1", uniqId );
  179. query_result = db_query( prop, query );
  180. num = db_num_rows(query_result);
  181. if(!num) return -1.0;
  182. else {
  183. db_get_field_assoc( query_result, "entX", query, 128 );
  184. x = floatstr( query );
  185. db_get_field_assoc( query_result, "entY", query, 128 );
  186. y = floatstr( query );
  187. db_get_field_assoc( query_result, "entZ", query, 128 );
  188. z = floatstr( query );
  189. db_get_field_assoc( query_result, "entA", query, 128 );
  190. return floatstr( query );
  191. }
  192. }
  193. stock dbSetPropertyOwner( database[], uniqId, ownerId ){
  194. }
  195. stock dbSetPropertyPrice( database[], uniqId, price ){
  196. }
  197. stock dbDeleteProperty( database[], uniqId ){
  198. }
  199. stock dbCreateProperty( database[], uniqId, Float:entX, Float:entY, Float:entZ, Float:entA ){ // remember to add rest of params
  200. }
  201. stock dbLoadProperties( database[] )
  202. {
  203. new
  204. DB:prop,
  205. DBResult:query_result,
  206. query[128],
  207. num,
  208. i;
  209. prop = db_open( database );
  210. format( query, 128,"SELECT * FROM properties", uniqId );
  211. query_result = db_query( prop, query );
  212. num = db_num_rows(query_result);
  213. if(!num) return 0;
  214. else {
  215. while( i < num ){
  216. db_get_field_assoc( query_result, "entX", query, 128 );
  217. x = floatstr( query );
  218. db_get_field_assoc( query_result, "entX", query, 128 );
  219. x = floatstr( query );
  220. db_get_field_assoc( query_result, "entY", query, 128 );
  221. y = floatstr( query );
  222. db_get_field_assoc( query_result, "entZ", query, 128 );
  223. z = floatstr( query );
  224. db_get_field_assoc( query_result, "entA", query, 128 );
  225. i++;
  226. }
  227. }
  228. }
  229. /********************************************************
  230. ********************************************************/
  231. /*********************************
  232. * Property System Functions *
  233. *********************************/
  234. ReadInteriorInfo( fileName[] )
  235. {
  236. new
  237. File:file_ptr,
  238. buf[256],
  239. tmp[64],
  240. idx,
  241. uniqId;
  242. file_ptr = fopen( fileName, io_read );
  243. if( file_ptr ){
  244. while( fread( file_ptr, buf, 256 ) > 0){
  245. idx = 0;
  246. idx = token_by_delim( buf, tmp, ' ', idx );
  247. if(idx == (-1)) continue;
  248. uniqId = strval( tmp );
  249. if( uniqId >= MAX_INTERIORS ) return 0;
  250. idx = token_by_delim( buf, tmp, ' ', idx+1 );
  251. if(idx == (-1)) continue;
  252. interiorInfo[uniqId][inIntID] = strval( tmp );
  253. idx = token_by_delim( buf, tmp, ' ', idx+1 );
  254. if(idx == (-1)) continue;
  255. interiorInfo[uniqId][inExitX] = floatstr( tmp );
  256. idx = token_by_delim( buf, tmp, ' ', idx+1 );
  257. if(idx == (-1)) continue;
  258. interiorInfo[uniqId][inExitY] = floatstr( tmp );
  259. idx = token_by_delim( buf, tmp, ' ', idx+1);
  260. if(idx == (-1)) continue;
  261. interiorInfo[uniqId][inExitZ] = floatstr( tmp );
  262. idx = token_by_delim( buf, tmp, ' ', idx+1 );
  263. if(idx == (-1)) continue;
  264. interiorInfo[uniqId][inExitA] = floatstr( tmp );
  265. idx = token_by_delim( buf, interiorInfo[uniqId][inName], ';', idx+1 );
  266. if(idx == (-1)) continue;
  267. /*
  268. printf( "ReadInteriorInfo(%d, %d, %f, %f, %f, %f ( %s ))",
  269. uniqId,
  270. interiorInfo[uniqId][inIntID],
  271. interiorInfo[uniqId][inExitX],
  272. interiorInfo[uniqId][inExitY],
  273. interiorInfo[uniqId][inExitZ],
  274. interiorInfo[uniqId][inExitA],
  275. interiorInfo[uniqId][inName] );*/
  276. }
  277. //printf( "Interiors File read successfully" );
  278. fclose( file_ptr );
  279. return 1;
  280. }
  281. printf( "Could Not Read Interiors file ( %s )", fileName );
  282. return 0;
  283. }
  284. ReadPropertyFile( fileName[] )
  285. {
  286. new File:file_ptr,
  287. tmp[128],
  288. buf[256],
  289. idx,
  290. Float:enX,
  291. Float:enY,
  292. Float:enZ,
  293. Float:enA,
  294. uniqIntId,
  295. p_type,
  296. pIcon;
  297. printf("Reading File: %s",fileName);
  298. file_ptr = fopen( fileName, io_read );
  299. if(!file_ptr )return 0;
  300. while( fread( file_ptr, buf, 256 ) > 0){
  301. idx = 0;
  302. idx = token_by_delim( buf, tmp, ',', idx );
  303. if(idx == (-1)) continue;
  304. pIcon = strval( tmp );
  305. idx = token_by_delim( buf, tmp, ',', idx+1 );
  306. if(idx == (-1)) continue;
  307. enX = floatstr( tmp );
  308. idx = token_by_delim( buf, tmp, ',', idx+1 );
  309. if(idx == (-1)) continue;
  310. enY = floatstr( tmp );
  311. idx = token_by_delim( buf, tmp, ',', idx+1 );
  312. if(idx == (-1)) continue;
  313. enZ = floatstr( tmp );
  314. idx = token_by_delim( buf, tmp, ',', idx+1 );
  315. if(idx == (-1)) continue;
  316. enA = floatstr( tmp );
  317. idx = token_by_delim( buf, tmp, ',', idx+1 );
  318. if(idx == (-1)) continue;
  319. uniqIntId = strval( tmp );
  320. idx = token_by_delim( buf, tmp, ';', idx+1 );
  321. if(idx == (-1)) continue;
  322. p_type = strval( tmp );
  323. CreateProperty( uniqIntId, pIcon, enX, enY, enZ, enA, p_type );
  324. }
  325. fclose( file_ptr );
  326. return 1;
  327. }
  328. PutPlayerInProperty( playerid, propId, propVW = 0 )
  329. {
  330. new Float:x, Float:y, Float:z, Float:a;
  331. new intFileId;
  332. a = GetPropertyExit( propId, x, y, z );
  333. SetPlayerPos( playerid, x, y, z );
  334. SetPlayerFacingAngle( playerid, a );
  335. SetPlayerInterior( playerid, GetPropertyInteriorId( propId ));
  336. SetPlayerVirtualWorld( playerid, (propVW==0)? propId+PROP_VW:propVW );
  337. intFileId = GetPropertyInteriorFileId(propId);
  338. currentInt[playerid] = propId;
  339. //new dbgstring[128];
  340. //format(dbgstring,sizeof(dbgstring),"PutPlayerInProperty(%d): FileInt=%d",propId,intFileId);
  341. //SendClientMessage(playerid,0xFFFFFFFF,dbgstring);
  342. // the following will make the client shop scripts run if we tell it
  343. // the name of the shop.
  344. if(intFileId == 22) {
  345. SetPlayerShopName(playerid,"FDPIZA");
  346. }
  347. else if(intFileId == 47) {
  348. SetPlayerShopName(playerid,"FDBURG");
  349. }
  350. else if(intFileId == 130) {
  351. SetPlayerShopName(playerid,"FDCHICK");
  352. }
  353. else if(intFileId == 32) {
  354. SetPlayerShopName(playerid,"AMMUN1");
  355. }
  356. else if(intFileId == 96) {
  357. SetPlayerShopName(playerid,"AMMUN2");
  358. }
  359. else if(intFileId == 122) {
  360. SetPlayerShopName(playerid,"AMMUN3");
  361. }
  362. else if(intFileId == 123) {
  363. SetPlayerShopName(playerid,"AMMUN5");
  364. }
  365. }
  366. // Adds new property to property file
  367. AddProperty( uniqIntId, Float:entX, Float:entY, Float:entZ, Float:entA, p_type, comment[]="" )
  368. {
  369. new
  370. Float:exitX,
  371. Float:exitY,
  372. Float:exitZ,
  373. Float:exitA,
  374. interiorId,
  375. File:file_ptr,
  376. tmp[128];
  377. interiorId = GetInteriorExitInfo( uniqIntId, exitX, exitY, exitZ, exitA );
  378. if( interiorId != -1 ){
  379. file_ptr = fopen( propFile[p_type], io_append );
  380. if(file_ptr){
  381. format( tmp, 128, "%d, %f, %f, %f, %f, %d, %d ; //%s\r\n", propIcons[p_type][tIcon],entX, entY, entZ, entA, uniqIntId, p_type, comment );
  382. fwrite( file_ptr, tmp );
  383. fclose( file_ptr );
  384. printf( "PropDB - %s", tmp );
  385. return CreateProperty( uniqIntId, propIcons[p_type][tIcon], entX, entY, entZ, entA, p_type );
  386. }
  387. }
  388. return -1;
  389. }
  390. CreateProperty( uniqIntId, iconId, Float:entX, Float:entY, Float:entZ, Float:entA, p_type, name[64]="", owner=-1, price=0 )
  391. {
  392. if( (unid+1) < MAX_PROPERTIES ){
  393. new Id = CreatePickup( iconId ,23, entX, entY, entZ, 0 );
  394. //printf( "CreateProperty(%d, %d, %f, %f, %f, %f, %d)", uniqIntId, iconId, entX, entY, entZ, entA, p_type );
  395. propPickups[Id] = unid;
  396. properties[unid][eEntX] = entX;
  397. properties[unid][eEntY] = entY;
  398. properties[unid][eEntZ] = entZ;
  399. properties[unid][eEntA] = entA;
  400. properties[unid][eUniqIntId] = uniqIntId;
  401. properties[unid][eOwner] = owner;
  402. properties[unid][ePrice] = price;
  403. properties[unid][eType] = p_type;
  404. format( properties[unid][ePname], 64, "%s", name );
  405. new text_info[256];
  406. propTextInfo[unid] = Text3D:INVALID_3DTEXT_ID;
  407. if(p_type == TYPE_HOUSE) {
  408. format(text_info,256,"{FFFFFF}[{88EE88}House{FFFFFF}]");
  409. propTextInfo[unid] = Create3DTextLabel(text_info,0x88EE88FF,entX,entY,entZ+0.75,20.0,0,1);
  410. }
  411. else if(p_type == TYPE_BUSINESS) {
  412. format(text_info,256,"{FFFFFF}[{AAAAFF}Business{FFFFFF}]");
  413. propTextInfo[unid] = Create3DTextLabel(text_info,0xAAAAFFFF,entX,entY,entZ+0.75,20.0,0,1);
  414. }
  415. else if(p_type == TYPE_BANK) {
  416. format(text_info,256,"{FFFFFF}[{EEEE88}Bank{FFFFFF}]");
  417. propTextInfo[unid] = Create3DTextLabel(text_info,0xEEEE88FF,entX,entY,entZ+0.75,20.0,0,1);
  418. }
  419. else if(p_type == TYPE_COP) {
  420. format(text_info,256,"{FFFFFF}[{EEEE88}Police Station{FFFFFF}]");
  421. propTextInfo[unid] = Create3DTextLabel(text_info,0xEEEE88FF,entX,entY,entZ+0.75,20.0,0,1);
  422. }
  423. return unid++;
  424. }
  425. else print( "Property Limit Reached" );
  426. return -1;
  427. }
  428. PropertyCommand( playerid, cmd[],cmdtext[],idx, p_type )
  429. {
  430. new
  431. Float:x,
  432. Float:y,
  433. Float:z,
  434. Float:a,
  435. tmp[256],
  436. string[128],
  437. uniqId,
  438. id;
  439. if( GetPlayerInterior(playerid) != 0 || GetPlayerVirtualWorld(playerid)!= 0 ){
  440. SendClientMessage(playerid, 0x550000FF, "You can only create properties in Interior 0 and VW 0" );
  441. return 1;
  442. }
  443. GetPlayerPos( playerid, x, y, z );
  444. GetPlayerFacingAngle( playerid, a );
  445. tmp = strtok( cmdtext, idx );
  446. if(!strlen(tmp)){
  447. format( string, 128, "Usage: %s [uniqInteriorId] [optional-comment]", cmd );
  448. SendClientMessage( playerid, 0xFF00CC, string );
  449. return 1;
  450. }
  451. if(!isNumeric(tmp)){
  452. SendClientMessage(playerid, 0x550000, "Uniq Interior Id must be a number" );
  453. return 1;
  454. }
  455. uniqId = strval( tmp );
  456. if( uniqId > MAX_INTERIORS || uniqId < 0 ){
  457. SendClientMessage( playerid, 0xFFFFCC, "Invalid Uniq Interior Id" );
  458. return 1;
  459. }
  460. idx = token_by_delim( cmdtext, tmp, '\0', idx );
  461. if(idx){
  462. id = AddProperty( uniqId, x, y, z, a, p_type, tmp );
  463. }
  464. else {
  465. id = AddProperty( uniqId, x, y, z, a, p_type );
  466. }
  467. if( id != -1 ){
  468. format( tmp, 256, "Property Type ( %d ) Added Successfully: UniqId: %d Interior: %d IntName: %s",p_type, id, interiorInfo[uniqId][inIntID], interiorInfo[uniqId][inName] );
  469. SendClientMessage( playerid, 0xCC7700, tmp );
  470. }else{
  471. SendClientMessage( playerid, 0x00FF55, "Error: Something went wrong/Property Limit Reached" );
  472. }
  473. return 1;
  474. }
  475. LoadProperties()
  476. {
  477. if( properties[0][eType] != TYPE_EMPTY ){
  478. UnloadProperties();
  479. }
  480. unid = 0;
  481. for( new i = 0; i < MAX_PROPERTIES; i++ ){
  482. properties[i][eType] = TYPE_EMPTY;
  483. }
  484. ReadInteriorInfo( "properties/interiors.txt" );
  485. for( new i = 0; i < MAX_TYPES; i++ ){
  486. ReadPropertyFile( propFile[i] );
  487. }
  488. return 1;
  489. }
  490. UnloadProperties()
  491. {
  492. new
  493. p;
  494. for( new i = 0; i < MAX_PROPERTIES; i++ ){
  495. if( propPickups[i] != -1 ){
  496. DestroyPickup( i );
  497. p = propPickups[i];
  498. propPickups[i] = -1;
  499. properties[p][eInterior] = -1;
  500. properties[p][eType] = TYPE_EMPTY;
  501. properties[p][eOwner] = -1;
  502. properties[p][ePrice] = 0;
  503. properties[p][ePname][0] = '\0';
  504. }
  505. }
  506. }
  507. /********************************************************
  508. ********************************************************/
  509. /************************************
  510. * Callbacks *
  511. ************************************/
  512. public OnFilterScriptInit()
  513. {
  514. print("\n-----------------------------------");
  515. print("Grand Larceny Property Filterscript ");
  516. print("-----------------------------------\n");
  517. return 1;
  518. }
  519. public OnFilterScriptExit()
  520. {
  521. UnloadProperties();
  522. return 1;
  523. }
  524. public OnGameModeInit()
  525. {
  526. LoadProperties();
  527. return 1;
  528. }
  529. public OnGameModeExit()
  530. {
  531. UnloadProperties();
  532. return 1;
  533. }
  534. public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid)
  535. {
  536. if( newinteriorid == 0 ){
  537. currentInt[playerid] = -1;
  538. SetPlayerVirtualWorld( playerid, 0 );
  539. }
  540. return 1;
  541. }
  542. public OnPlayerSpawn( playerid )
  543. {
  544. gLastPropertyEnterNotification[playerid] = -1;
  545. return 1;
  546. }
  547. public OnPlayerPickUpPickup(playerid, pickupid)
  548. {
  549. //printf( "DEBUG: Player %d pickedup Pickup %d Prop Id %d", playerid, pickupid );
  550. lastPickup[playerid] = pickupid;
  551. new id = propPickups[pickupid];
  552. new pmsg[256];
  553. if( properties[id][eType] > 0 ){
  554. if(gLastPropertyEnterNotification[playerid] != id){
  555. gLastPropertyEnterNotification[playerid] = id;
  556. switch( properties[id][eType] ){
  557. case TYPE_HOUSE:{
  558. format(pmsg,256,"* House: type /enter to enter");
  559. SendClientMessage( playerid, 0xFF55BBFF, pmsg );
  560. return 1;
  561. }
  562. case TYPE_BUSINESS:{
  563. format(pmsg,256,"* Business: type /enter to enter");
  564. SendClientMessage( playerid, 0xFF55BBFF, pmsg );
  565. return 1;
  566. }
  567. case TYPE_BANK:{
  568. format(pmsg,256,"* Bank: type /enter to enter");
  569. SendClientMessage( playerid, 0xFF55BBFF, pmsg );
  570. return 1;
  571. }
  572. case TYPE_COP:{
  573. format(pmsg,256,"* Police Station: type /enter to enter");
  574. SendClientMessage( playerid, 0xFF55BBFF, pmsg );
  575. return 1;
  576. }
  577. }
  578. }
  579. }
  580. else SendClientMessage( playerid, 0xFF9900FF, "This property doesn't exist :S" );
  581. return 1;
  582. }
  583. public OnPlayerCommandText(playerid, cmdtext[])
  584. {
  585. new idx;
  586. new cmd[256];
  587. cmd = strtok(cmdtext, idx);
  588. // Public commands.
  589. if(strcmp("/enter", cmd, true) == 0) // enter property
  590. {
  591. if( lastPickup[playerid] != -1 || properties[lastPickup[playerid]][eType] > 0 ){
  592. new
  593. id = propPickups[lastPickup[playerid]],
  594. Float:x,
  595. Float:y,
  596. Float:z;
  597. GetPropertyEntrance( id, x, y, z );
  598. if( IsPlayerInRangeOfPoint( playerid, 3.0, x, y, z )){
  599. PutPlayerInProperty( playerid, id );
  600. SendClientMessage( playerid, 0x55AADDFF, "* You have entered a property.. type /exit to leave" );
  601. return 1;
  602. }
  603. }
  604. return 1;
  605. }
  606. else if(strcmp("/exit", cmd, true) == 0) // exit property
  607. {
  608. if( currentInt[playerid] > -1 && GetPlayerInterior(playerid) == GetPropertyInteriorId( currentInt[playerid] )){
  609. new id = currentInt[playerid];
  610. new Float:x;
  611. new Float:y;
  612. new Float:z;
  613. new Float:a;
  614. // make sure they're near the exit before allowing them to exit.
  615. GetPropertyExit( id, x, y, z );
  616. if(!IsPlayerInRangeOfPoint(playerid,4.5,x,y,z)) {
  617. SendClientMessage(playerid,0xDDAA55FF,"* You must be near the property exit to /exit");
  618. return 1;
  619. }
  620. a = GetPropertyEntrance( id, x, y, z );
  621. SetPlayerPos( playerid, x, y, z );
  622. SetPlayerFacingAngle( playerid, a );
  623. SetPlayerInterior( playerid, 0 );
  624. SetPlayerVirtualWorld( playerid, 0 );
  625. }
  626. currentInt[playerid] = -1;
  627. return 1;
  628. }
  629. // The rest of the commands here are for
  630. // property creation which is admin only.
  631. if(!IsPlayerAdmin(playerid)) return 0;
  632. if(strcmp("/chouse", cmd, true) == 0) // creates a house type property
  633. {
  634. PropertyCommand( playerid, cmd, cmdtext,idx, TYPE_HOUSE );
  635. return 1;
  636. }
  637. else if(strcmp("/cbus", cmd, true) == 0) // creates a business type property
  638. {
  639. PropertyCommand( playerid, cmd, cmdtext,idx, TYPE_BUSINESS );
  640. return 1;
  641. }
  642. else if(strcmp("/ccop", cmd, true) == 0) // creates a police station property
  643. {
  644. PropertyCommand( playerid, cmd, cmdtext,idx, TYPE_COP );
  645. return 1;
  646. }
  647. else if(strcmp("/cbank", cmd, true) == 0) // creates a bank type property
  648. {
  649. PropertyCommand( playerid, cmd, cmdtext,idx, TYPE_BANK );
  650. return 1;
  651. }
  652. else if(strcmp("/view", cmd, true) == 0) //Basically lets you view an interior from the interiors.txt file by id
  653. {
  654. new
  655. tmp[256],
  656. string[128],
  657. uniqId,
  658. Float:x,
  659. Float:y,
  660. Float:z,
  661. Float:a;
  662. tmp = strtok( cmdtext, idx );
  663. if(!strlen(tmp)){
  664. format( string, 128, "Usage: %s [uniqInteriorId]", cmd );
  665. SendClientMessage( playerid, 0xFF00CC, string );
  666. return 1;
  667. }
  668. if(!isNumeric(tmp)){
  669. SendClientMessage(playerid, 0x550000, "Uniq Interior Id must be a number" );
  670. return 1;
  671. }
  672. uniqId = strval( tmp );
  673. if( uniqId > MAX_INTERIORS || uniqId < 0 ){
  674. SendClientMessage( playerid, 0xFFFFCC, "Invalid Uniq Interior Id" );
  675. return 1;
  676. }
  677. if( GetPlayerInterior( playerid ) == 0 ){
  678. GetPlayerPos( playerid, plPos[playerid][0], plPos[playerid][1], plPos[playerid][2] );
  679. plInt[playerid] = GetPlayerInterior( playerid );
  680. }
  681. a = GetInteriorExit( uniqId, x, y, z );
  682. SetPlayerInterior( playerid, GetInteriorIntID( uniqId ) );
  683. SetPlayerPos( playerid, x, y, z );
  684. SetPlayerFacingAngle( playerid, a );
  685. format( string, 128, "UniqId: %d InteriorId: %d Name: %s | Use /return to go to last position", uniqId,GetInteriorIntID( uniqId ), GetInteriorName( uniqId ));
  686. SendClientMessage( playerid, 0x556600FF, string );
  687. return 1;
  688. }
  689. else if( strcmp( "/return", cmd, true ) == 0 ) // return from /view command to last position
  690. {
  691. SetPlayerPos( playerid, plPos[playerid][0], plPos[playerid][1], plPos[playerid][2] );
  692. SetPlayerInterior( playerid, plInt[playerid] );
  693. return 1;
  694. }
  695. return 0;
  696. }
  697. /***********************************************************************
  698. ***********************************************************************/