1
0

y_td.inc 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047
  1. /*----------------------------------------------------------------------------*-
  2. ===============================
  3. y_td - Stlyes for text draws!
  4. ===============================
  5. Description:
  6. Provides a wrapper to the SA:MP text_draw functions offering much
  7. improved functionality including XML definable styles, safe display,
  8. timed displays, styles and text separated, styles updateable dynamically
  9. and more.
  10. Legal:
  11. Version: MPL 1.1
  12. The contents of this file are subject to the Mozilla Public License Version
  13. 1.1 (the "License"); you may not use this file except in compliance with
  14. the License. You may obtain a copy of the License at
  15. http://www.mozilla.org/MPL/
  16. Software distributed under the License is distributed on an "AS IS" basis,
  17. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  18. for the specific language governing rights and limitations under the
  19. License.
  20. The Original Code is the SA:MP script information include.
  21. The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  22. Portions created by the Initial Developer are Copyright (C) 2008
  23. the Initial Developer. All Rights Reserved.
  24. Contributors:
  25. ZeeX, koolk
  26. Thanks:
  27. Peter, Cam - Support.
  28. ZeeX - Very productive conversations.
  29. koolk - IsPlayerinAreaEx code.
  30. TheAlpha - Danish translation.
  31. breadfish - German translation.
  32. Fireburn - Dutch translation.
  33. yom - French translation.
  34. 50p - Polish translation.
  35. Zamaroht - Spanish translation.
  36. Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes
  37. for me to strive to better.
  38. Pixels^ - Running XScripters where the idea was born.
  39. Matite - Pestering me to release it and using it.
  40. Very special thanks to:
  41. Thiadmer - PAWN.
  42. Kye/Kalcor - SA:MP.
  43. SA:MP Team past, present and future - SA:MP.
  44. Version:
  45. 1.0
  46. Changelog:
  47. 06/08/10:
  48. First version
  49. -*----------------------------------------------------------------------------*/
  50. #include <YSI\internal\y_version>
  51. #define ALS_PREFIX TD
  52. #include <YSI\y_als>
  53. #include <YSI\y_debug>
  54. #include <YSI\y_bit>
  55. #include <YSI\y_xml>
  56. #include <YSI\y_utils>
  57. #include <YSI\y_colours>
  58. #include <foreach>
  59. //#include <YSI\y_timer>
  60. #include <a_samp>
  61. #if !defined MAX_TEXT_DRAW_STYLES
  62. #define MAX_TEXT_DRAW_STYLES (Style:32)
  63. #endif
  64. #define MAX_TEXT_DRAW_LINE (128)
  65. #define TEXT_DRAW_NO_NEXT (Text:-1)
  66. #define TEXT_DRAW_NAN (0xFFFFFFFF)
  67. //#define TEXT_DRAW_NO_STYLE_NAME
  68. #tryinclude <sscanf2>
  69. enum td_align
  70. {
  71. td_align_none,
  72. td_align_left,
  73. td_align_center,
  74. td_align_centre = td_align_center,
  75. td_align_right
  76. }
  77. enum e_TD_BITS (<<= 1)
  78. {
  79. e_TD_BITS_SHADOW = 0x000000FF,
  80. e_TD_BITS_OUTLINE = 0x0000FF00,
  81. e_TD_BITS_ALIGN = 0x000F0000,
  82. e_TD_BITS_FONT = 0x00F00000,
  83. e_TD_BITS_BOX = 0x01000000,
  84. e_TD_BITS_PROP
  85. }
  86. enum E_TD_DATA
  87. {
  88. #if !defined TEXT_DRAW_NO_STYLE_NAME
  89. E_TD_DATA_NAME[MAX_XML_ENTRY_NAME char],
  90. #endif
  91. E_TD_DATA_HASH,
  92. Float:E_TD_DATA_X,
  93. Float:E_TD_DATA_Y,
  94. Float:E_TD_DATA_LX,
  95. Float:E_TD_DATA_LY,
  96. Float:E_TD_DATA_TX,
  97. Float:E_TD_DATA_TY,
  98. E_TD_DATA_COLOUR,
  99. e_TD_BITS:E_TD_DATA_BITS,
  100. E_TD_DATA_BOX,
  101. E_TD_DATA_BG,
  102. E_TD_DATA_TIME,
  103. Text:E_TD_DATA_USE,
  104. E_TD_DATA_UPDATE
  105. }
  106. enum E_TD_DISPLAY
  107. {
  108. Float:E_TD_DISPLAY_X,
  109. Float:E_TD_DISPLAY_Y,
  110. Text:E_TD_DISPLAY_NEXT,
  111. Style:E_TD_DISPLAY_STYLE,
  112. E_TD_DISPLAY_LIFE,
  113. Text:E_TD_DISPLAY_REAL,
  114. E_TD_DISPLAY_REVISION,
  115. E_TD_DISPLAY_TEXT[MAX_TEXT_DRAW_LINE char]
  116. }
  117. forward TD_LoadColour();
  118. forward TD_Textdraw();
  119. forward TD_HideForPlayerPub(playerid, Text:textDraw, revision);
  120. static stock
  121. XML:YSI_g_sXMLRules = NO_XML_FILE,
  122. YSI_g_sTDData[MAX_TEXT_DRAW_STYLES][E_TD_DATA],
  123. YSI_g_sTDDisplay[Text:MAX_TEXT_DRAWS][E_TD_DISPLAY],
  124. //YSI_g_sTDTimers[Text:MAX_TEXT_DRAWS][MAX_PLAYERS],
  125. // This is actually dual purpose.
  126. Text:YSI_g_sUnused,
  127. BitArray:YSI_g_sPlayerDraws[MAX_PLAYERS]<MAX_TEXT_DRAWS>;
  128. //Bit:YSI_g_sPlayerDraws[MAX_PLAYERS][Bit_Bits(MAX_TEXT_DRAWS)];
  129. ALS_DATA<>
  130. //static stock TD_SetTimer(playerid, Text:td, time, revision)
  131. //{
  132. // SetTimerEx("TD_HideForPlayer", time, 0, "iii", playerid, _:td, revision);
  133. //}
  134. #define TD_SetTimer(%0,%1,%2,%3) SetTimerEx("TD_HideForPlayerPub", (%2), 0, "iii", (%0), _:(%1), (%3))
  135. /*----------------------------------------------------------------------------*-
  136. Function:
  137. TD_IsValidStyle
  138. Params:
  139. Style:id - Text draw style to check validity of,
  140. Return:
  141. -
  142. Notes:
  143. -
  144. -*----------------------------------------------------------------------------*/
  145. #define TD_IsValidStyle(%1) \
  146. (Style:0 <= (%1) < MAX_TEXT_DRAW_STYLES && YSI_g_sTDData[(%1)][E_TD_DATA_HASH])
  147. #define _TD_IsValid(%1) \
  148. ((%1) < MAX_TEXT_DRAW_STYLES && YSI_g_sTDData[(%1)][E_TD_DATA_HASH])
  149. #define _TD_TextValid(%0) \
  150. (Text:0 <= (%0) < Text:MAX_TEXT_DRAWS && YSI_g_sTDDisplay[(%0)][E_TD_DISPLAY_TEXT][0])
  151. /*----------------------------------------------------------------------------*-
  152. Function:
  153. TD_TD
  154. Params:
  155. -
  156. Return:
  157. -
  158. Notes:
  159. Constructor.
  160. -*----------------------------------------------------------------------------*/
  161. #if defined FILTERSCRIPT
  162. public OnFilterScriptInit()
  163. #else
  164. public OnGameModeInit()
  165. #endif
  166. {
  167. if (YSI_g_sXMLRules == NO_XML_FILE)
  168. {
  169. YSI_g_sXMLRules = XML_New();
  170. if (YSI_g_sXMLRules != NO_XML_FILE)
  171. {
  172. XML_AddHandler(YSI_g_sXMLRules, "color", "TD_LoadColour");
  173. XML_AddHandler(YSI_g_sXMLRules, "colour", "TD_LoadColour");
  174. XML_AddHandler(YSI_g_sXMLRules, "textdraw", "TD_Textdraw");
  175. //XML_AddHandler(YSI_g_sXMLRules, "box", "TD_Box");
  176. //XML_AddHandler(YSI_g_sXMLRules, "background", "TD_Background");
  177. //XML_AddHandler(YSI_g_sXMLRules, "style", "TD_Style");
  178. }
  179. }
  180. for (new Text:i; Text:i < Text:MAX_TEXT_DRAWS; i++)
  181. {
  182. YSI_g_sTDDisplay[i][E_TD_DISPLAY_REAL] = Text:INVALID_TEXT_DRAW;
  183. YSI_g_sTDDisplay[i][E_TD_DISPLAY_NEXT] = i + Text:1;
  184. }
  185. YSI_g_sTDDisplay[Text:(MAX_TEXT_DRAWS - 1)][E_TD_DISPLAY_NEXT] = TEXT_DRAW_NO_NEXT;
  186. ALS_DETECT<PlayerDisconnect>
  187. CallLocalFunction("TD_OnScriptInit", "");
  188. return 1;
  189. }
  190. #if defined FILTERSCRIPT
  191. #if defined _ALS_OnFilterScriptInit
  192. #undef OnFilterScriptInit
  193. #else
  194. #define _ALS_OnFilterScriptInit
  195. #endif
  196. #define OnFilterScriptInit TD_OnScriptInit
  197. #else
  198. #if defined _ALS_OnGameModeInit
  199. #undef OnGameModeInit
  200. #else
  201. #define _ALS_OnGameModeInit
  202. #endif
  203. #define OnGameModeInit TD_OnScriptInit
  204. #endif
  205. forward TD_OnScriptInit();
  206. /*----------------------------------------------------------------------------*-
  207. Function:
  208. TD_Parse
  209. Params:
  210. filename[] - File to parse as a textdraw data file.
  211. Return:
  212. -
  213. Notes:
  214. -
  215. -*----------------------------------------------------------------------------*/
  216. stock TD_Parse(filename[])
  217. {
  218. return XML_Parse(YSI_g_sXMLRules, filename);
  219. }
  220. /*----------------------------------------------------------------------------*-
  221. Function:
  222. TD_LoadColour
  223. Params:
  224. -
  225. Return:
  226. -
  227. Notes:
  228. XML callback for loading the <colour> tag.
  229. -*----------------------------------------------------------------------------*/
  230. public TD_LoadColour()
  231. {
  232. P:2("TD_LoadColour called");
  233. static
  234. name[MAX_XML_ENTRY_NAME],
  235. val[MAX_XML_ENTRY_TEXT];
  236. new
  237. colour,
  238. hash;
  239. while (XML_GetKeyValue(name, val))
  240. {
  241. if (!strcmp(name, "name", true))
  242. {
  243. hash = COLOUR_NAME_HASH(val);
  244. }
  245. else if (!strcmp(name, "hex", true))
  246. {
  247. #if defined _inc_sscanf2
  248. unformat(val, "x", colour);
  249. #else
  250. colour = hexstr(val);
  251. #endif
  252. }
  253. else if (!strcmp(name, "value", true))
  254. {
  255. #if defined _inc_sscanf2
  256. if (unformat(val, "n", colour))
  257. #else
  258. if (ishex(val)) colour = hexstr(val);
  259. else if (isnumeric(val)) colour = strval(val);
  260. else
  261. #endif
  262. colour = GetColour(val);
  263. }
  264. }
  265. //if (hash) Text_SetColour(hash, colour);
  266. if (hash) SetColourHash(hash, colour);
  267. return colour;
  268. }
  269. /*----------------------------------------------------------------------------*-
  270. Function:
  271. TD_Create
  272. Params:
  273. Float:x - X position the text will appear at.
  274. Float:y - Y position the text will appear at,
  275. Float:letterX - Letter X size.
  276. Float:letterY - Letter Y size.
  277. Float:textX - Box X size.
  278. Float:textY - Box Y size.
  279. colour - Text colour.
  280. boxColour - Colour of the text box.
  281. bgColour - Colour of the text background.
  282. shadow - Text shadow size.
  283. outline - Text outline size.
  284. align - Text alignment.
  285. font - Text font style.
  286. bool:proportional - Wether to make the text proportional.
  287. bool:box - Wether to use a box.
  288. time - Time for the text to display in ms (0 = infinate).
  289. name[] - Name of the style.
  290. Return:
  291. -
  292. Notes:
  293. Creates a text draw style structure according to given
  294. parameters, can be used to display any text in the given
  295. style without repeated redefinitions.
  296. -*----------------------------------------------------------------------------*/
  297. stock Style:TD_Create(Float:x = 0.0, Float:y = 0.0, Float:letterX = 0.48, Float:letterY = 1.12, Float:textX = 1280.0, Float:textY = 1280.0, colour = 0xE1E1E1FF, boxColour = 0x80808080, bgColour = 0x000000FF, shadow = 2, outline = 0, align = _:td_align_none, font = 1, bool:proportional = false, bool:box = false, time = 0, name[] = "\1")
  298. {
  299. new
  300. Style:i;
  301. while (_TD_IsValid(i))
  302. {
  303. ++i;
  304. }
  305. if (i == MAX_TEXT_DRAW_STYLES)
  306. {
  307. return MAX_TEXT_DRAW_STYLES;
  308. }
  309. #if !defined TEXT_DRAW_NO_STYLE_NAME
  310. strpack(YSI_g_sTDData[i][E_TD_DATA_NAME], name, MAX_XML_ENTRY_NAME);
  311. #endif
  312. YSI_g_sTDData[i][E_TD_DATA_HASH] = bernstein(name);
  313. YSI_g_sTDData[i][E_TD_DATA_X] = x;
  314. YSI_g_sTDData[i][E_TD_DATA_Y] = y;
  315. YSI_g_sTDData[i][E_TD_DATA_LX] = letterX;
  316. YSI_g_sTDData[i][E_TD_DATA_LY] = letterY;
  317. YSI_g_sTDData[i][E_TD_DATA_TX] = textX;
  318. YSI_g_sTDData[i][E_TD_DATA_TY] = textY;
  319. YSI_g_sTDData[i][E_TD_DATA_COLOUR] = colour;
  320. YSI_g_sTDData[i][E_TD_DATA_BITS] =
  321. ((box) ? (e_TD_BITS_BOX) : (e_TD_BITS:0)) |
  322. ((proportional) ? (e_TD_BITS_PROP) : (e_TD_BITS:0)) |
  323. (e_TD_BITS:(shadow << 0) & e_TD_BITS_SHADOW) |
  324. (e_TD_BITS:(outline << 8) & e_TD_BITS_OUTLINE) |
  325. (e_TD_BITS:(align << 16) & e_TD_BITS_ALIGN) |
  326. (e_TD_BITS:(font << 20) & e_TD_BITS_FONT);
  327. YSI_g_sTDData[i][E_TD_DATA_BOX] = boxColour;
  328. YSI_g_sTDData[i][E_TD_DATA_BG] = bgColour;
  329. YSI_g_sTDData[i][E_TD_DATA_TIME] = time;
  330. YSI_g_sTDData[i][E_TD_DATA_USE] = TEXT_DRAW_NO_NEXT;
  331. YSI_g_sTDData[i][E_TD_DATA_UPDATE] = -1;
  332. return Style:i;
  333. }
  334. /*----------------------------------------------------------------------------*-
  335. Function:
  336. TD_Textdraw
  337. Params:
  338. -
  339. Return:
  340. -
  341. Notes:
  342. XML callback for loading the <textdraw> tag.
  343. -*----------------------------------------------------------------------------*/
  344. public TD_Textdraw()
  345. {
  346. // Set all the default values quickly.
  347. new
  348. Style:i = TD_Create();
  349. if (i != MAX_TEXT_DRAW_STYLES)
  350. {
  351. static
  352. name[MAX_XML_ENTRY_NAME],
  353. val[MAX_XML_ENTRY_TEXT];
  354. new
  355. e_TD_BITS:bits,
  356. // Bernstein hash of 1.
  357. hash = -32;
  358. // !"\1"
  359. //YSI_g_sTDData[i][E_TD_DATA_NAME] = 0x01000000;
  360. while (XML_GetKeyValue(name, val))
  361. {
  362. if (!strcmp(name, "x", true))
  363. {
  364. YSI_g_sTDData[i][E_TD_DATA_X] = floatstr(val);
  365. }
  366. else if (!strcmp(name, "y", true))
  367. {
  368. YSI_g_sTDData[i][E_TD_DATA_Y] = floatstr(val);
  369. }
  370. else if (!strcmp(name, "letterx", true))
  371. {
  372. YSI_g_sTDData[i][E_TD_DATA_LX] = floatstr(val);
  373. }
  374. else if (!strcmp(name, "lettery", true))
  375. {
  376. YSI_g_sTDData[i][E_TD_DATA_LY] = floatstr(val);
  377. }
  378. else if (!strcmp(name, "textx", true))
  379. {
  380. YSI_g_sTDData[i][E_TD_DATA_TX] = floatstr(val);
  381. }
  382. else if (!strcmp(name, "texty", true))
  383. {
  384. YSI_g_sTDData[i][E_TD_DATA_TY] = floatstr(val);
  385. }
  386. else if (!strcmp(name, "alignment", true))
  387. {
  388. bits &= ~e_TD_BITS_ALIGN;
  389. if (!strcmp(val, "left", true)) bits |= e_TD_BITS:(_:td_align_left << 16) & e_TD_BITS_ALIGN;
  390. else if (!strcmp(val, "right", true)) bits |= e_TD_BITS:(_:td_align_right << 16) & e_TD_BITS_ALIGN;
  391. else if (!strcmp(val, "center", true) || !strcmp(val, "centre", true)) bits |= e_TD_BITS:(_:td_align_center << 16) & e_TD_BITS_ALIGN;
  392. }
  393. else if (!strcmp(name, "color", true) || !strcmp(name, "colour", true))
  394. {
  395. P:2("TD_Textdraw: colour called");
  396. // This could now be done with the sscanf "n" type for "number".
  397. #if defined _inc_sscanf2
  398. new
  399. colour;
  400. if (!unformat(val, "n", colour)) YSI_g_sTDData[i][E_TD_DATA_COLOUR] = colour;
  401. #else
  402. if (ishex(val)) YSI_g_sTDData[i][E_TD_DATA_COLOUR] = hexstr(val);
  403. else if (isnumeric(val)) YSI_g_sTDData[i][E_TD_DATA_COLOUR] = strval(val);
  404. #endif
  405. else YSI_g_sTDData[i][E_TD_DATA_COLOUR] = GetColour(val);
  406. }
  407. else if (!strcmp(name, "box", true))
  408. {
  409. new
  410. box = strval(val);
  411. if (box)
  412. {
  413. bits |= e_TD_BITS_BOX;
  414. YSI_g_sTDData[i][E_TD_DATA_BOX] = box;
  415. }
  416. }
  417. else if (!strcmp(name, "shadow", true))
  418. {
  419. bits = (bits & ~e_TD_BITS_SHADOW) | (e_TD_BITS:(strval(val)) & e_TD_BITS_SHADOW);
  420. }
  421. else if (!strcmp(name, "outline", true))
  422. {
  423. bits = (bits & ~e_TD_BITS_OUTLINE) | (e_TD_BITS:(strval(val) << 8) & e_TD_BITS_OUTLINE);
  424. }
  425. else if (!strcmp(name, "background", true))
  426. {
  427. #if defined _inc_sscanf2
  428. new
  429. colour;
  430. if (!unformat(val, "n", colour)) YSI_g_sTDData[i][E_TD_DATA_BG] = colour;
  431. #else
  432. if (ishex(val)) YSI_g_sTDData[i][E_TD_DATA_BG] = hexstr(val);
  433. else if (isnumeric(val)) YSI_g_sTDData[i][E_TD_DATA_BG] = strval(val);
  434. #endif
  435. else YSI_g_sTDData[i][E_TD_DATA_BG] = GetColour(val);
  436. P:5("TD_Textdraw(): Background color: \"%s\", %d, %d: 0x%04x%04x", val, ishex(val), isnumeric(val), YSI_g_sTDData[i][E_TD_DATA_BG] >>> 16, YSI_g_sTDData[i][E_TD_DATA_BG] & 0xFFFF);
  437. }
  438. else if (!strcmp(name, "font", true))
  439. {
  440. bits = (bits & ~e_TD_BITS_FONT) | (e_TD_BITS:(strval(val) << 20) & e_TD_BITS_FONT);
  441. }
  442. else if (!strcmp(name, "proportional", true))
  443. {
  444. bits |= e_TD_BITS_PROP;
  445. }
  446. else if (!strcmp(name, "time", true))
  447. {
  448. YSI_g_sTDData[i][E_TD_DATA_TIME] = strval(val);
  449. }
  450. else if (!strcmp(name, "name", true))
  451. {
  452. #if !defined TEXT_DRAW_NO_STYLE_NAME
  453. strpack(YSI_g_sTDData[i][E_TD_DATA_NAME], val, MAX_XML_ENTRY_NAME);
  454. #endif
  455. hash = bernstein(val);
  456. }
  457. }
  458. YSI_g_sTDData[i][E_TD_DATA_BITS] = bits;
  459. /*if (!(YSI_g_sTDData[i][E_TD_DATA_NAME] & 0xFF000000))
  460. {
  461. YSI_g_sTDData[i][E_TD_DATA_NAME] = 0x01000000;
  462. }*/
  463. //YSI_g_sTDData[i][E_TD_DATA_HASH] = bernstein(YSI_g_sTDData[i][E_TD_DATA_NAME]);
  464. YSI_g_sTDData[i][E_TD_DATA_HASH] = hash;
  465. P:5("TD data: %.2f %.2f %.2f %.2f %.2f %.2f %x %d %x %d %d", YSI_g_sTDData[i][E_TD_DATA_X], YSI_g_sTDData[i][E_TD_DATA_Y], YSI_g_sTDData[i][E_TD_DATA_LX], YSI_g_sTDData[i][E_TD_DATA_LY], YSI_g_sTDData[i][E_TD_DATA_TX], YSI_g_sTDData[i][E_TD_DATA_TY], YSI_g_sTDData[i][E_TD_DATA_COLOUR], YSI_g_sTDData[i][E_TD_DATA_BOX], YSI_g_sTDData[i][E_TD_DATA_BG], YSI_g_sTDData[i][E_TD_DATA_TIME], YSI_g_sTDData[i][E_TD_DATA_BITS]);//, YSI_g_sTDData[i][E_TD_DATA_NAME]);
  466. }
  467. return _:i;
  468. }
  469. /*----------------------------------------------------------------------------*-
  470. Function:
  471. TD_GetID
  472. Params:
  473. hash - Hash of a style name to get a style index for.
  474. Return:
  475. -
  476. Notes:
  477. -
  478. -*----------------------------------------------------------------------------*/
  479. stock Style:TD_GetID(hash)
  480. {
  481. new
  482. Style:i;
  483. while (i != MAX_TEXT_DRAW_STYLES && YSI_g_sTDData[i][E_TD_DATA_HASH] != hash)
  484. {
  485. ++i;
  486. }
  487. return i;
  488. }
  489. /*----------------------------------------------------------------------------*-
  490. Function:
  491. TD_Create
  492. Params:
  493. Style:styleID - Style to clone.
  494. name[] - Name of the new style.
  495. Return:
  496. -
  497. Notes:
  498. Copies a text draw style and returns the new handle.
  499. -*----------------------------------------------------------------------------*/
  500. //#if 0
  501. stock Style:TD_Clone(Style:styleID, name[] = "\1")
  502. {
  503. if (!TD_IsValidStyle(styleID))
  504. {
  505. return MAX_TEXT_DRAW_STYLES;
  506. }
  507. new
  508. Style:i;
  509. while (_TD_IsValid(i))
  510. {
  511. i++;
  512. }
  513. if (i == MAX_TEXT_DRAW_STYLES)
  514. {
  515. return MAX_TEXT_DRAW_STYLES;
  516. }
  517. #if !defined TEXT_DRAW_NO_STYLE_NAME
  518. strpack(YSI_g_sTDData[i][E_TD_DATA_NAME], name, MAX_XML_ENTRY_NAME);
  519. #endif
  520. YSI_g_sTDData[i][E_TD_DATA_HASH] = bernstein(name);
  521. // memcpy?
  522. YSI_g_sTDData[i][E_TD_DATA_X] = YSI_g_sTDData[styleID][E_TD_DATA_X];
  523. YSI_g_sTDData[i][E_TD_DATA_Y] = YSI_g_sTDData[styleID][E_TD_DATA_Y];
  524. YSI_g_sTDData[i][E_TD_DATA_LX] = YSI_g_sTDData[styleID][E_TD_DATA_LX];
  525. YSI_g_sTDData[i][E_TD_DATA_LY] = YSI_g_sTDData[styleID][E_TD_DATA_LY];
  526. YSI_g_sTDData[i][E_TD_DATA_TX] = YSI_g_sTDData[styleID][E_TD_DATA_TX];
  527. YSI_g_sTDData[i][E_TD_DATA_TY] = YSI_g_sTDData[styleID][E_TD_DATA_TY];
  528. YSI_g_sTDData[i][E_TD_DATA_COLOUR] = YSI_g_sTDData[styleID][E_TD_DATA_COLOUR];
  529. YSI_g_sTDData[i][E_TD_DATA_BITS] = YSI_g_sTDData[styleID][E_TD_DATA_BITS];
  530. YSI_g_sTDData[i][E_TD_DATA_BOX] = YSI_g_sTDData[styleID][E_TD_DATA_BOX];
  531. YSI_g_sTDData[i][E_TD_DATA_BG] = YSI_g_sTDData[styleID][E_TD_DATA_BG];
  532. YSI_g_sTDData[i][E_TD_DATA_TIME] = YSI_g_sTDData[styleID][E_TD_DATA_TIME];
  533. YSI_g_sTDData[i][E_TD_DATA_USE] = TEXT_DRAW_NO_NEXT;
  534. YSI_g_sTDData[i][E_TD_DATA_UPDATE] = -1;
  535. return Style:i;
  536. }
  537. /*----------------------------------------------------------------------------*-
  538. Function:
  539. TD_Name
  540. Params:
  541. Style:styleID - Style to modify.
  542. name[] - Name to give the style.
  543. Return:
  544. -
  545. Notes:
  546. -
  547. -*----------------------------------------------------------------------------*/
  548. stock TD_Name(Style:styleID, name[])
  549. {
  550. if (!TD_IsValidStyle(styleID))
  551. {
  552. return 0;
  553. }
  554. #if !defined TEXT_DRAW_NO_STYLE_NAME
  555. strpack(YSI_g_sTDData[styleID][E_TD_DATA_NAME], name, MAX_XML_ENTRY_NAME);
  556. #endif
  557. YSI_g_sTDData[styleID][E_TD_DATA_HASH] = bernstein(name);
  558. return 1;
  559. }
  560. /*----------------------------------------------------------------------------*-
  561. Function:
  562. TD_TextPosition
  563. Params:
  564. Text:textID - Text to modify.
  565. Float:x - New horizontal position.
  566. Float:y - New vertical position.
  567. Return:
  568. -
  569. Notes:
  570. Moves a single bit of text, not all with a style.
  571. -*----------------------------------------------------------------------------*/
  572. stock TD_TextPosition(Text:textID, Float:x, Float:y)
  573. {
  574. if (!_TD_TextValid(textID))
  575. {
  576. return 0;
  577. }
  578. YSI_g_sTDDisplay[textID][E_TD_DISPLAY_X] = x;
  579. YSI_g_sTDDisplay[textID][E_TD_DISPLAY_Y] = y;
  580. TD_UpdateOne(textID, YSI_g_sTDDisplay[textID][E_TD_DISPLAY_STYLE]);
  581. return 1;
  582. }
  583. /*----------------------------------------------------------------------------*-
  584. Function:
  585. TD_TextXPos
  586. Params:
  587. Text:textID - Text to modify.
  588. Float:x - New horizontal position.
  589. Return:
  590. -
  591. Notes:
  592. Moves a single bit of text, not all with a style.
  593. -*----------------------------------------------------------------------------*/
  594. stock TD_TextXPos(Text:textID, Float:x)
  595. {
  596. if (!_TD_TextValid(textID))
  597. {
  598. return 0;
  599. }
  600. YSI_g_sTDDisplay[textID][E_TD_DISPLAY_X] = x;
  601. TD_UpdateOne(textID, YSI_g_sTDDisplay[textID][E_TD_DISPLAY_STYLE]);
  602. return 1;
  603. }
  604. /*----------------------------------------------------------------------------*-
  605. Function:
  606. TD_TextYPos
  607. Params:
  608. Text:textID - Text to modify.
  609. Float:y - New vertical position.
  610. Return:
  611. -
  612. Notes:
  613. Moves a single bit of text, not all with a style.
  614. -*----------------------------------------------------------------------------*/
  615. stock TD_TextYPos(Text:textID, Float:y)
  616. {
  617. if (!_TD_TextValid(textID))
  618. {
  619. return 0;
  620. }
  621. YSI_g_sTDDisplay[textID][E_TD_DISPLAY_Y] = y;
  622. TD_UpdateOne(textID, YSI_g_sTDDisplay[textID][E_TD_DISPLAY_STYLE]);
  623. return 1;
  624. }
  625. /*----------------------------------------------------------------------------*-
  626. Function:
  627. TD_StylePosition
  628. Params:
  629. Style:styleID - Style to modify.
  630. Float:x - New horizontal position.
  631. Float:y - New vertical position.
  632. bool:update - Wether to update the appearence for players.
  633. Return:
  634. -
  635. Notes:
  636. Update is default false to not modify moved texts.
  637. -*----------------------------------------------------------------------------*/
  638. stock TD_StylePosition(Style:styleID, Float:x, Float:y)
  639. {
  640. if (!TD_IsValidStyle(styleID))
  641. {
  642. return 0;
  643. }
  644. YSI_g_sTDData[styleID][E_TD_DATA_X] = x;
  645. YSI_g_sTDData[styleID][E_TD_DATA_Y] = y;
  646. if (update) TD_Update(styleID, true);
  647. return 1;
  648. }
  649. /*----------------------------------------------------------------------------*-
  650. Function:
  651. TD_StyleXPos
  652. Params:
  653. Style:styleID - Style to modify.
  654. Float:x - New horizontal position.
  655. bool:update - Wether to update the appearence for players.
  656. Return:
  657. -
  658. Notes:
  659. Update is default false to not modify moved texts.
  660. -*----------------------------------------------------------------------------*/
  661. stock TD_StyleXPos(Style:styleID, Float:x)
  662. {
  663. if (!TD_IsValidStyle(styleID))
  664. {
  665. return 0;
  666. }
  667. YSI_g_sTDData[styleID][E_TD_DATA_X] = x;
  668. if (update) TD_Update(styleID, true);
  669. return 1;
  670. }
  671. /*----------------------------------------------------------------------------*-
  672. Function:
  673. TD_StyleYPos
  674. Params:
  675. Style:styleID - Style to modify.
  676. Float:y - New vertical position.
  677. bool:update - Wether to update the appearence for players.
  678. Return:
  679. -
  680. Notes:
  681. Update is default false to not modify moved texts.
  682. -*----------------------------------------------------------------------------*/
  683. stock TD_StyleYPos(Style:styleID, Float:y)
  684. {
  685. if (!TD_IsValidStyle(styleID))
  686. {
  687. return 0;
  688. }
  689. YSI_g_sTDData[styleID][E_TD_DATA_Y] = y;
  690. if (update) TD_Update(styleID, true);
  691. return 1;
  692. }
  693. /*----------------------------------------------------------------------------*-
  694. Function:
  695. TD_LetterSize
  696. Params:
  697. Style:styleID - Style to modify.
  698. Float:x - New letter width.
  699. Float:y - New letter height.
  700. bool:update - Wether to update the appearence for players.
  701. Return:
  702. -
  703. Notes:
  704. -
  705. -*----------------------------------------------------------------------------*/
  706. stock TD_LetterSize(Style:styleID, Float:x, Float:y)
  707. {
  708. if (!TD_IsValidStyle(styleID))
  709. {
  710. return 0;
  711. }
  712. YSI_g_sTDData[styleID][E_TD_DATA_LX] = x;
  713. YSI_g_sTDData[styleID][E_TD_DATA_LY] = y;
  714. TD_Update(styleID);
  715. return 1;
  716. }
  717. /*----------------------------------------------------------------------------*-
  718. Function:
  719. TD_LetterX
  720. Params:
  721. Style:styleID - Style to modify.
  722. Float:x - New letter width.
  723. bool:update - Wether to update the appearence for players.
  724. Return:
  725. -
  726. Notes:
  727. -
  728. -*----------------------------------------------------------------------------*/
  729. stock TD_LetterX(Style:styleID, Float:x)
  730. {
  731. if (!TD_IsValidStyle(styleID))
  732. {
  733. return 0;
  734. }
  735. YSI_g_sTDData[styleID][E_TD_DATA_LX] = x;
  736. TD_Update(styleID);
  737. return 1;
  738. }
  739. /*----------------------------------------------------------------------------*-
  740. Function:
  741. TD_LetterY
  742. Params:
  743. Style:styleID - Style to modify.
  744. Float:y - New letter height.
  745. bool:update - Wether to update the appearence for players.
  746. Return:
  747. -
  748. Notes:
  749. -
  750. -*----------------------------------------------------------------------------*/
  751. stock TD_LetterY(Style:styleID, Float:y)
  752. {
  753. if (!TD_IsValidStyle(styleID))
  754. {
  755. return 0;
  756. }
  757. YSI_g_sTDData[styleID][E_TD_DATA_LY] = y;
  758. TD_Update(styleID);
  759. return 1;
  760. }
  761. /*----------------------------------------------------------------------------*-
  762. Function:
  763. TD_TextSize
  764. Params:
  765. Style:styleID - Style to modify.
  766. Float:x - New text width.
  767. Float:y - New text height.
  768. bool:update - Wether to update the appearence for players.
  769. Return:
  770. -
  771. Notes:
  772. -
  773. -*----------------------------------------------------------------------------*/
  774. stock TD_TextSize(Style:styleID, Float:x, Float:y)
  775. {
  776. if (!TD_IsValidStyle(styleID))
  777. {
  778. return 0;
  779. }
  780. YSI_g_sTDData[styleID][E_TD_DATA_TX] = x;
  781. YSI_g_sTDData[styleID][E_TD_DATA_TY] = y;
  782. TD_Update(styleID);
  783. return 1;
  784. }
  785. /*----------------------------------------------------------------------------*-
  786. Function:
  787. TD_TextX
  788. Params:
  789. Style:styleID - Style to modify.
  790. Float:x - New text width.
  791. bool:update - Wether to update the appearence for players.
  792. Return:
  793. -
  794. Notes:
  795. -
  796. -*----------------------------------------------------------------------------*/
  797. stock TD_TextX(Style:styleID, Float:x)
  798. {
  799. if (!TD_IsValidStyle(styleID))
  800. {
  801. return 0;
  802. }
  803. YSI_g_sTDData[styleID][E_TD_DATA_TX] = x;
  804. TD_Update(styleID);
  805. return 1;
  806. }
  807. /*----------------------------------------------------------------------------*-
  808. Function:
  809. TD_TextY
  810. Params:
  811. Style:styleID - Style to modify.
  812. Float:y - New text height.
  813. bool:update - Wether to update the appearence for players.
  814. Return:
  815. -
  816. Notes:
  817. -
  818. -*----------------------------------------------------------------------------*/
  819. stock TD_TextY(Style:styleID, Float:y)
  820. {
  821. if (!TD_IsValidStyle(styleID))
  822. {
  823. return 0;
  824. }
  825. YSI_g_sTDData[styleID][E_TD_DATA_TY] = y;
  826. TD_Update(styleID);
  827. return 1;
  828. }
  829. /*----------------------------------------------------------------------------*-
  830. Function:
  831. TD_Alignment
  832. Params:
  833. Style:styleID - Style to modify.
  834. alignment - Where to align the text in it's box.
  835. bool:update - Wether to update the appearence for players.
  836. Return:
  837. -
  838. Notes:
  839. Designed to take ta_align enum values and numbers.
  840. -*----------------------------------------------------------------------------*/
  841. stock TD_Alignment(Style:styleID, alignment = _:td_align_none)
  842. {
  843. if (!TD_IsValidStyle(styleID))
  844. {
  845. return 0;
  846. }
  847. YSI_g_sTDData[styleID][E_TD_DATA_BITS] = (YSI_g_sTDData[styleID][E_TD_DATA_BITS] & ~e_TD_BITS_ALIGN) | (e_TD_BITS:(alignment << 16) & e_TD_BITS_ALIGN);
  848. TD_Update(styleID);
  849. return 1;
  850. }
  851. /*----------------------------------------------------------------------------*-
  852. Function:
  853. TD_Colour
  854. Params:
  855. Style:styleID - Style to modify.
  856. colour - New text colour.
  857. bool:update - Wether to update the appearence for players.
  858. Return:
  859. -
  860. Notes:
  861. -
  862. -*----------------------------------------------------------------------------*/
  863. stock TD_Colour(Style:styleID, colour)
  864. {
  865. if (!TD_IsValidStyle(styleID))
  866. {
  867. return 0;
  868. }
  869. YSI_g_sTDData[styleID][E_TD_DATA_COLOUR] = colour;
  870. TD_Update(styleID);
  871. return 1;
  872. }
  873. #define TD_Color TD_Colour
  874. /*----------------------------------------------------------------------------*-
  875. Function:
  876. TD_UseBox
  877. Params:
  878. Style:styleID - Style to modify.
  879. bool:use - Wether or not to show a box round the text.
  880. bool:update - Wether to update the appearence for players.
  881. Return:
  882. -
  883. Notes:
  884. -
  885. -*----------------------------------------------------------------------------*/
  886. stock TD_UseBox(Style:styleID, bool:use)
  887. {
  888. if (!TD_IsValidStyle(styleID))
  889. {
  890. return 0;
  891. }
  892. if (use) YSI_g_sTDData[styleID][E_TD_DATA_BITS] |= e_TD_BITS_BOX;
  893. else YSI_g_sTDData[styleID][E_TD_DATA_BITS] &= ~e_TD_BITS_BOX;
  894. TD_Update(styleID);
  895. return 1;
  896. }
  897. /*----------------------------------------------------------------------------*-
  898. Function:
  899. TD_BoxColour
  900. Params:
  901. Style:styleID - Style to modify.
  902. colour - New box colour.
  903. bool:update - Wether to update the appearence for players.
  904. Return:
  905. -
  906. Notes:
  907. -
  908. -*----------------------------------------------------------------------------*/
  909. stock TD_BoxColour(Style:styleID, colour)
  910. {
  911. if (!TD_IsValidStyle(styleID))
  912. {
  913. return 0;
  914. }
  915. YSI_g_sTDData[styleID][E_TD_DATA_BOX] = colour;
  916. TD_Update(styleID);
  917. return 1;
  918. }
  919. #define TD_BoxColor TD_BoxColour
  920. /*----------------------------------------------------------------------------*-
  921. Function:
  922. TD_SetShadow
  923. Params:
  924. Style:styleID - Style to modify.
  925. size - Size of the letter shadow,
  926. bool:update - Wether to update the appearence for players.
  927. Return:
  928. -
  929. Notes:
  930. -
  931. -*----------------------------------------------------------------------------*/
  932. stock TD_SetShadow(Style:styleID, size)
  933. {
  934. if (!TD_IsValidStyle(styleID))
  935. {
  936. return 0;
  937. }
  938. YSI_g_sTDData[styleID][E_TD_DATA_BITS] = (YSI_g_sTDData[styleID][E_TD_DATA_BITS] & ~e_TD_BITS_SHADOW) | (e_TD_BITS:(size) & e_TD_BITS_SHADOW);
  939. TD_Update(styleID);
  940. return 1;
  941. }
  942. /*----------------------------------------------------------------------------*-
  943. Function:
  944. TD_SetOutline
  945. Params:
  946. Style:styleID - Style to modify.
  947. size - Size of the letter outline.
  948. bool:update - Wether to update the appearence for players.
  949. Return:
  950. -
  951. Notes:
  952. -
  953. -*----------------------------------------------------------------------------*/
  954. stock TD_SetOutline(Style:styleID, size)
  955. {
  956. if (!TD_IsValidStyle(styleID))
  957. {
  958. return 0;
  959. }
  960. YSI_g_sTDData[styleID][E_TD_DATA_BITS] = (YSI_g_sTDData[styleID][E_TD_DATA_BITS] & ~e_TD_BITS_OUTLINE) | (e_TD_BITS:(size << 8) & e_TD_BITS_OUTLINE);
  961. TD_Update(styleID);
  962. return 1;
  963. }
  964. /*----------------------------------------------------------------------------*-
  965. Function:
  966. TD_BackgroundColour
  967. Params:
  968. Style:styleID - Style to modify.
  969. colour - New background (outline/shadow) colour.
  970. bool:update - Wether to update the appearence for players.
  971. Return:
  972. -
  973. Notes:
  974. -
  975. -*----------------------------------------------------------------------------*/
  976. stock TD_BackgroundColour(Style:styleID, colour)
  977. {
  978. if (!TD_IsValidStyle(styleID))
  979. {
  980. return 0;
  981. }
  982. YSI_g_sTDData[styleID][E_TD_DATA_BG] = colour;
  983. TD_Update(styleID);
  984. return 1;
  985. }
  986. #define TD_BackgroundColor TD_BackgroundColour
  987. /*----------------------------------------------------------------------------*-
  988. Function:
  989. TD_Font
  990. Params:
  991. Style:styleID - Style to modify.
  992. font - New text font style.
  993. bool:update - Wether to update the appearence for players.
  994. Return:
  995. -
  996. Notes:
  997. -
  998. -*----------------------------------------------------------------------------*/
  999. stock TD_Font(Style:styleID, font)
  1000. {
  1001. if (!TD_IsValidStyle(styleID))
  1002. {
  1003. return 0;
  1004. }
  1005. YSI_g_sTDData[styleID][E_TD_DATA_BITS] = (YSI_g_sTDData[styleID][E_TD_DATA_BITS] & ~e_TD_BITS_FONT) | (e_TD_BITS:(font << 20) & e_TD_BITS_FONT);
  1006. TD_Update(styleID);
  1007. return 1;
  1008. }
  1009. /*----------------------------------------------------------------------------*-
  1010. Function:
  1011. TD_SetProportional
  1012. Params:
  1013. Style:styleID - Style to modify.
  1014. bool:set - Wether to make the letters proportional or not.
  1015. bool:update - Wether to update the appearence for players.
  1016. Return:
  1017. -
  1018. Notes:
  1019. -
  1020. -*----------------------------------------------------------------------------*/
  1021. stock TD_SetProportional(Style:styleID, bool:set)
  1022. {
  1023. if (!TD_IsValidStyle(styleID))
  1024. {
  1025. return 0;
  1026. }
  1027. if (set) YSI_g_sTDData[styleID][E_TD_DATA_BITS] |= e_TD_BITS_PROP;
  1028. else YSI_g_sTDData[styleID][E_TD_DATA_BITS] &= ~e_TD_BITS_PROP;
  1029. TD_Update(styleID);
  1030. return 1;
  1031. }
  1032. /*----------------------------------------------------------------------------*-
  1033. Function:
  1034. TD_SetTime
  1035. Params:
  1036. Style:styleID - Style to modify.
  1037. time - New time for the text to display for.
  1038. existing - Whether or not to change the display of existing text draws.
  1039. Return:
  1040. -
  1041. Notes:
  1042. Doesn't update existing timed texts, just new ones. Now does all of them.
  1043. -*----------------------------------------------------------------------------*/
  1044. stock TD_SetTime(Style:styleID, time, bool:existing = false)
  1045. {
  1046. if (!TD_IsValidStyle(styleID))
  1047. {
  1048. return 0;
  1049. }
  1050. YSI_g_sTDData[styleID][E_TD_DATA_TIME] = time;
  1051. if (existing)
  1052. {
  1053. // Hide this after the given time for all players.
  1054. new
  1055. Text:next = YSI_g_sTDData[styleId][E_TD_DATA_USE],
  1056. Text:last = TEXT_DRAW_NO_NEXT;
  1057. while (next != TEXT_DRAW_NO_NEXT)
  1058. {
  1059. // DO update the revision here!
  1060. new
  1061. index = Bit_Slot(next),
  1062. Bit:mod = Bit_Mask(next),
  1063. revision = ++YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REVISION];
  1064. foreach (Player, playerid)
  1065. {
  1066. if (YSI_g_sPlayerDraws[playerid][index] & mod)
  1067. {
  1068. TD_SetTimer(playerid, next, time, revision);
  1069. }
  1070. }
  1071. last = next;
  1072. next = YSI_g_sTDDisplay[next][E_TD_DISPLAY_NEXT];
  1073. }
  1074. }
  1075. return 1;
  1076. }
  1077. /*----------------------------------------------------------------------------*-
  1078. Function:
  1079. Text:TD_Render
  1080. Params:
  1081. text[] - String to output.
  1082. Style:id - Text draw style to render the text in.
  1083. Text:slot - the slot the text is stored in.
  1084. Return:
  1085. TextDraw id.
  1086. Notes:
  1087. Basically the application layer, creates a text_draw with the
  1088. saved data.
  1089. -*----------------------------------------------------------------------------*/
  1090. static stock Text:TD_Render(text[], Style:id, Text:slot)
  1091. {
  1092. new
  1093. Text:textDraw = TextDrawCreate(YSI_g_sTDDisplay[slot][E_TD_DISPLAY_X], YSI_g_sTDDisplay[slot][E_TD_DISPLAY_Y], text);
  1094. if (textDraw != Text:INVALID_TEXT_DRAW)
  1095. {
  1096. new
  1097. e_TD_BITS:bits = YSI_g_sTDData[id][E_TD_DATA_BITS];
  1098. TextDrawLetterSize(textDraw, YSI_g_sTDData[id][E_TD_DATA_LX], YSI_g_sTDData[id][E_TD_DATA_LY]);
  1099. TextDrawTextSize(textDraw, YSI_g_sTDData[id][E_TD_DATA_TX], YSI_g_sTDData[id][E_TD_DATA_TY]);
  1100. TextDrawAlignment(textDraw, _:(bits & e_TD_BITS_ALIGN) >> 16);
  1101. TextDrawColor(textDraw, YSI_g_sTDData[id][E_TD_DATA_COLOUR]);
  1102. TextDrawUseBox(textDraw, (bits & e_TD_BITS_BOX) ? 1 : 0);
  1103. TextDrawBoxColor(textDraw, YSI_g_sTDData[id][E_TD_DATA_BOX]);
  1104. TextDrawSetShadow(textDraw, _:(bits & e_TD_BITS_SHADOW));
  1105. TextDrawSetOutline(textDraw, _:(bits & e_TD_BITS_OUTLINE) >> 8);
  1106. TextDrawBackgroundColor(textDraw, YSI_g_sTDData[id][E_TD_DATA_BG]);
  1107. TextDrawFont(textDraw, _:(bits & e_TD_BITS_FONT) >> 20);
  1108. TextDrawSetProportional(textDraw, (bits & e_TD_BITS_PROP) ? 1 : 0);
  1109. }
  1110. return textDraw;
  1111. }
  1112. /*----------------------------------------------------------------------------*-
  1113. Function:
  1114. TD_Update
  1115. Params:
  1116. Style:id - Style to update for players.
  1117. bool:pos - Wether or not to update children's positions.
  1118. Return:
  1119. -
  1120. Notes:
  1121. Loops through all texts displayed using the current render
  1122. style and updates their real display.
  1123. -*----------------------------------------------------------------------------*/
  1124. stock TD_Update(Style:id, bool:pos = false)
  1125. {
  1126. if (!TD_IsValidStyle(id))
  1127. {
  1128. return;
  1129. }
  1130. new
  1131. Text:next = YSI_g_sTDData[id][E_TD_DATA_USE],
  1132. Float:x,
  1133. Float:y;
  1134. if (pos)
  1135. {
  1136. x = YSI_g_sTDData[id][E_TD_DATA_X],
  1137. y = YSI_g_sTDData[id][E_TD_DATA_Y];
  1138. }
  1139. while (next != TEXT_DRAW_NO_NEXT)
  1140. {
  1141. if (pos)
  1142. {
  1143. YSI_g_sTDDisplay[next][E_TD_DISPLAY_X] = x;
  1144. YSI_g_sTDDisplay[next][E_TD_DISPLAY_Y] = y;
  1145. }
  1146. //TD_UpdateOne(next, id);
  1147. next = YSI_g_sTDDisplay[next][E_TD_DISPLAY_NEXT];
  1148. }
  1149. // Update the apperance after a load of updates have been applied.
  1150. if (YSI_g_sTDData[id][E_TD_DATA_UPDATE] == -1)
  1151. {
  1152. YSI_g_sTDData[id][E_TD_DATA_UPDATE] = SetTimerEx("TD_UpdateInternal", 1, 0, "i", _:id);
  1153. }
  1154. }
  1155. forward TD_UpdateInternal(Style:id);
  1156. public TD_UpdateInternal(Style:id)
  1157. {
  1158. new
  1159. Text:next = YSI_g_sTDData[id][E_TD_DATA_USE];
  1160. while (next != TEXT_DRAW_NO_NEXT)
  1161. {
  1162. TD_UpdateOne(next, id);
  1163. next = YSI_g_sTDDisplay[next][E_TD_DISPLAY_NEXT];
  1164. }
  1165. }
  1166. /*----------------------------------------------------------------------------*-
  1167. Function:
  1168. TD_UpdateOne
  1169. Params:
  1170. Text:slot - Text to update.
  1171. Style:id - Style to use.
  1172. Return:
  1173. -
  1174. Notes:
  1175. Updates a single text's appearance. Modified to use a timer with a delay of
  1176. 1ms, to be called after the current slew of updates. This means that doing
  1177. a whole load of modifications at once will all be committed to players at
  1178. the same time. This used to be done with the optional "update" parameter.
  1179. -*----------------------------------------------------------------------------*/
  1180. stock TD_UpdateOne(Text:slot, Style:id)
  1181. {
  1182. // DON'T update the revision in here - if you show a TD to a player for 5
  1183. // seconds and change it after 2, they should just get the new version for
  1184. // 3 seconds, it shouldn't reset the timer.
  1185. new
  1186. Text:real = YSI_g_sTDDisplay[slot][E_TD_DISPLAY_REAL];
  1187. TextDrawDestroy(real);
  1188. real = TD_Render(YSI_g_sTDDisplay[slot][E_TD_DISPLAY_TEXT], id, slot);
  1189. YSI_g_sTDDisplay[slot][E_TD_DISPLAY_REAL] = real;
  1190. if (real != Text:INVALID_TEXT_DRAW)
  1191. {
  1192. new
  1193. index = Bit_Slot(slot),
  1194. Bit:mod = Bit_Mask(slot);
  1195. foreach (Player, playerid)
  1196. {
  1197. if (YSI_g_sPlayerDraws[playerid][index] & mod)
  1198. {
  1199. TextDrawShowForPlayer(playerid, real);
  1200. }
  1201. }
  1202. }
  1203. }
  1204. /*----------------------------------------------------------------------------*-
  1205. Function:
  1206. TD_Delete
  1207. Params:
  1208. styleId - Text draw style ID you want to remove.
  1209. Return:
  1210. -
  1211. Notes:
  1212. Just nulls the name to remove it's active marker.
  1213. -*----------------------------------------------------------------------------*/
  1214. stock TD_Delete(Style:styleId)
  1215. {
  1216. if (!TD_IsValidStyle(styleId))
  1217. {
  1218. return 0;
  1219. }
  1220. if (YSI_g_sTDData[styleId][E_TD_DATA_UPDATE] != -1)
  1221. {
  1222. KillTimer(YSI_g_sTDData[styleId][E_TD_DATA_UPDATE]);
  1223. YSI_g_sTDData[styleId][E_TD_DATA_UPDATE] = -1;
  1224. }
  1225. new
  1226. Text:next = YSI_g_sTDData[styleId][E_TD_DATA_USE],
  1227. Text:last = TEXT_DRAW_NO_NEXT;
  1228. // Loop through all the TDs using this style.
  1229. while (next != TEXT_DRAW_NO_NEXT)
  1230. {
  1231. TextDrawDestroy(YSI_g_sTDDisplay[next][E_TD_DISPLAY_REAL]);
  1232. YSI_g_sTDDisplay[next][E_TD_DISPLAY_REAL] = Text:INVALID_TEXT_DRAW;
  1233. YSI_g_sTDDisplay[next][E_TD_DISPLAY_TEXT][0] = '\0';
  1234. ++YSI_g_sTDDisplay[next][E_TD_DISPLAY_REVISION];
  1235. new
  1236. index = Bit_Slot(next),
  1237. Bit:mod = ~Bit_Mask(next);
  1238. foreach (Player, playerid)
  1239. {
  1240. // TODO: Update.
  1241. /*if (YSI_g_sTDTimers[next][playerid])
  1242. {
  1243. KillTimer(YSI_g_sTDTimers[next][playerid]);
  1244. }
  1245. YSI_g_sTDTimers[next][playerid] = 0;*/
  1246. // Kill the update timer.
  1247. // Mark this player as not having this TD.
  1248. YSI_g_sPlayerDraws[playerid][index] &= mod;
  1249. }
  1250. last = next;
  1251. next = YSI_g_sTDDisplay[next][E_TD_DISPLAY_NEXT];
  1252. }
  1253. // Add the entire style list to the unused list at once.
  1254. if (last != TEXT_DRAW_NO_NEXT)
  1255. {
  1256. // There are items to add.
  1257. YSI_g_sTDDisplay[last][E_TD_DISPLAY_NEXT] = YSI_g_sUnused;
  1258. YSI_g_sUnused = YSI_g_sTDData[styleId][E_TD_DATA_USE];
  1259. }
  1260. // Mark the style as unused.
  1261. YSI_g_sTDData[styleId][E_TD_DATA_USE] = TEXT_DRAW_NO_NEXT;
  1262. #if !defined TEXT_DRAW_NO_STYLE_NAME
  1263. YSI_g_sTDData[styleId][E_TD_DATA_NAME] = 0;
  1264. #endif
  1265. YSI_g_sTDData[styleId][E_TD_DATA_HASH] = 0;
  1266. return 1;
  1267. }
  1268. /*----------------------------------------------------------------------------*-
  1269. Function:
  1270. TD_TryDestroy
  1271. Params:
  1272. Text:textDraw - Text draw to destroy safely.
  1273. Return:
  1274. -
  1275. Notes:
  1276. Destroys this text draw only if it is marked for garbage collection. It
  1277. does not however check that no-one can see the text draw, so those people
  1278. who can currently see it will loose it.
  1279. -*----------------------------------------------------------------------------*/
  1280. static stock TD_TryDestroy(Text:textDraw)
  1281. {
  1282. // Destroy this if it is marked to be garbage collected.
  1283. if (YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_LIFE] & 0x80000000)
  1284. {
  1285. TD_Destroy(textDraw);
  1286. return 1;
  1287. }
  1288. return 0;
  1289. }
  1290. /*----------------------------------------------------------------------------*-
  1291. Function:
  1292. TD_Destroy
  1293. Params:
  1294. Text:textDraw - Text draw to destroy safely.
  1295. Return:
  1296. -
  1297. Notes:
  1298. Optimised for multiple people. Not very well though...
  1299. -*----------------------------------------------------------------------------*/
  1300. stock TD_Destroy(Text:textDraw)
  1301. {
  1302. if (Text:0 <= textDraw < Text:MAX_TEXT_DRAWS)
  1303. {
  1304. // Find the TD before this one in the style list.
  1305. new
  1306. Style:style = YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_STYLE],
  1307. Text:next = YSI_g_sTDData[style][E_TD_DATA_USE],
  1308. Text:last = TEXT_DRAW_NO_NEXT;
  1309. while (next != TEXT_DRAW_NO_NEXT)
  1310. {
  1311. if (next == textDraw)
  1312. {
  1313. break;
  1314. }
  1315. last = next;
  1316. next = YSI_g_sTDDisplay[next][E_TD_DISPLAY_NEXT];
  1317. }
  1318. // Destroy the SA:MP text draw.
  1319. new
  1320. Text:real = YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REAL];
  1321. YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REAL] = Text:INVALID_TEXT_DRAW;
  1322. YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_TEXT][0] = '\0';
  1323. ++YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REVISION];
  1324. if (real != Text:INVALID_TEXT_DRAW)
  1325. {
  1326. // TextDrawDestroy
  1327. TextDrawDestroy(real);
  1328. // Now kill timers for players.
  1329. // TODO: Update.
  1330. new
  1331. index = Bit_Slot(textDraw),
  1332. Bit:mod = ~Bit_Mask(textDraw);
  1333. foreach (Player, playerid)
  1334. {
  1335. /*if (YSI_g_sTDTimers[textDraw][playerid])
  1336. {
  1337. KillTimer(YSI_g_sTDTimers[textDraw][playerid]);
  1338. }
  1339. YSI_g_sTDTimers[textDraw][playerid] = 0;*/
  1340. YSI_g_sPlayerDraws[playerid][index] &= mod;
  1341. }
  1342. }
  1343. // Remove from the style use list and add to the unused list.
  1344. if (next != textDraw)
  1345. {
  1346. return 0;
  1347. }
  1348. C:1(else printf("*** Internal Error: Orphaned text draw found."););
  1349. if (last == TEXT_DRAW_NO_NEXT)
  1350. {
  1351. YSI_g_sTDData[style][E_TD_DATA_USE] = YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_NEXT];
  1352. }
  1353. else
  1354. {
  1355. YSI_g_sTDDisplay[last][E_TD_DISPLAY_NEXT] = YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_NEXT];
  1356. }
  1357. YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_NEXT] = YSI_g_sUnused;
  1358. YSI_g_sUnused = textDraw;
  1359. }
  1360. return 1;
  1361. }
  1362. /*----------------------------------------------------------------------------*-
  1363. Function:
  1364. Text:TD_Display
  1365. Params:
  1366. text[] - Text to display onscreen.
  1367. Style:id - Style to use to style text.
  1368. Return:
  1369. Internal Text: id, not actual text draw's id.
  1370. Notes:
  1371. Generates a text draw for to display to people.
  1372. -*----------------------------------------------------------------------------*/
  1373. stock Text:TD_Display(text[], Style:id, Float:x = (Float:TEXT_DRAW_NAN), Float:y = (Float:TEXT_DRAW_NAN))
  1374. {
  1375. if (YSI_g_sUnused == TEXT_DRAW_NO_NEXT)
  1376. {
  1377. return Text:INVALID_TEXT_DRAW;
  1378. }
  1379. if (!TD_IsValidStyle(id))
  1380. {
  1381. return Text:INVALID_TEXT_DRAW;
  1382. }
  1383. // if (x != x)
  1384. // Determine the screen position.
  1385. if (_:x == TEXT_DRAW_NAN)
  1386. {
  1387. YSI_g_sTDDisplay[YSI_g_sUnused][E_TD_DISPLAY_X] = YSI_g_sTDData[id][E_TD_DATA_X];
  1388. }
  1389. else
  1390. {
  1391. YSI_g_sTDDisplay[YSI_g_sUnused][E_TD_DISPLAY_X] = x;
  1392. }
  1393. if (_:y == TEXT_DRAW_NAN)
  1394. {
  1395. YSI_g_sTDDisplay[YSI_g_sUnused][E_TD_DISPLAY_Y] = YSI_g_sTDData[id][E_TD_DATA_Y];
  1396. }
  1397. else
  1398. {
  1399. YSI_g_sTDDisplay[YSI_g_sUnused][E_TD_DISPLAY_Y] = y;
  1400. }
  1401. YSI_g_sTDDisplay[YSI_g_sUnused][E_TD_DISPLAY_STYLE] = id;
  1402. // Render the code to an internal TD. All TD_Render does is call SA:MP
  1403. // functions, it does no variable sets.
  1404. new
  1405. Text:textDraw = TD_Render(text, id, YSI_g_sUnused);
  1406. if (textDraw == Text:INVALID_TEXT_DRAW)
  1407. {
  1408. return Text:INVALID_TEXT_DRAW;
  1409. }
  1410. YSI_g_sTDDisplay[YSI_g_sUnused][E_TD_DISPLAY_REAL] = textDraw;
  1411. // I don't know wether or not to use strpack here.
  1412. //strcpy(YSI_g_sTDDisplay[YSI_g_sUnused][E_TD_DISPLAY_TEXT], text, MAX_TEXT_DRAW_LINE);
  1413. strpack(YSI_g_sTDDisplay[YSI_g_sUnused][E_TD_DISPLAY_TEXT], text, MAX_TEXT_DRAW_LINE char);
  1414. textDraw = Text:YSI_g_sUnused;
  1415. YSI_g_sUnused = YSI_g_sTDDisplay[YSI_g_sUnused][E_TD_DISPLAY_NEXT];
  1416. // Add to the list of items using this style.
  1417. YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_NEXT] = YSI_g_sTDData[id][E_TD_DATA_USE];
  1418. YSI_g_sTDData[id][E_TD_DATA_USE] = textDraw;
  1419. // Nobody can see it, but don't destroy it.
  1420. YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_LIFE] = 0;
  1421. // Increment this every time this slot is used and cleared.
  1422. ++YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REVISION];
  1423. return textDraw;
  1424. }
  1425. stock Text:TD_DisplayForPlayer(playerid, text[], Style:id, Float:x = (Float:TEXT_DRAW_NAN), Float:y = (Float:TEXT_DRAW_NAN))
  1426. {
  1427. new
  1428. Text:td = TD_Display(text, id, x, y);
  1429. TD_Garbage(td);
  1430. TD_ShowForPlayer(playerid, td);
  1431. return td;
  1432. }
  1433. stock Text:TD_DisplayForAll(text[], Style:id, Float:x = (Float:TEXT_DRAW_NAN), Float:y = (Float:TEXT_DRAW_NAN))
  1434. {
  1435. new
  1436. Text:td = TD_Display(text, id, x, y);
  1437. TD_Garbage(td);
  1438. TD_ShowForAll(td);
  1439. return td;
  1440. }
  1441. /*----------------------------------------------------------------------------*-
  1442. Function:
  1443. TD_SetString
  1444. Params:
  1445. Text:td - The text draw to modify.
  1446. text[] - Text to display onscreen.
  1447. Return:
  1448. -
  1449. Notes:
  1450. Changes the text on people's screens quickly.
  1451. -*----------------------------------------------------------------------------*/
  1452. stock TD_SetString(Text:td, text[])
  1453. {
  1454. if (_TD_TextValid(td))
  1455. {
  1456. //strcpy(YSI_g_sTDDisplay[td][E_TD_DISPLAY_TEXT], text, MAX_TEXT_DRAW_LINE);
  1457. strpack(YSI_g_sTDDisplay[td][E_TD_DISPLAY_TEXT], text, MAX_TEXT_DRAW_LINE char);
  1458. new
  1459. Text:real = YSI_g_sTDDisplay[td][E_TD_DISPLAY_REAL];
  1460. // This may have lost it's real rendering
  1461. if (real == Text:INVALID_TEXT_DRAW)
  1462. {
  1463. return 0;
  1464. }
  1465. // Get the style information for showing this TD.
  1466. TextDrawSetString(real, text);
  1467. }
  1468. return 1;
  1469. }
  1470. /*----------------------------------------------------------------------------*-
  1471. Function:
  1472. Text:TD_DisplayHashed
  1473. Params:
  1474. text[] - Text to display.
  1475. hash - Hashed style name for styling.
  1476. Return:
  1477. -
  1478. Notes:
  1479. -
  1480. -*----------------------------------------------------------------------------*/
  1481. stock Text:TD_DisplayHashed(text[], hash, Float:x = (Float:TEXT_DRAW_NAN), Float:y = (Float:TEXT_DRAW_NAN))
  1482. {
  1483. new
  1484. Style:id = TD_GetID(hash);
  1485. if (id != MAX_TEXT_DRAW_STYLES)
  1486. {
  1487. return TD_Display(text, id, x, y);
  1488. }
  1489. return Text:INVALID_TEXT_DRAW;
  1490. }
  1491. stock Text:TD_DisplayHashedForPlayer(playerid, text[], hash, Float:x = (Float:TEXT_DRAW_NAN), Float:y = (Float:TEXT_DRAW_NAN))
  1492. {
  1493. new
  1494. Style:id = TD_GetID(hash);
  1495. if (id != MAX_TEXT_DRAW_STYLES)
  1496. {
  1497. return TD_DisplayForPlayer(playerid, text, id, x, y);
  1498. }
  1499. return Text:INVALID_TEXT_DRAW;
  1500. }
  1501. stock Text:TD_DisplayHashedForAll(text[], hash, Float:x = (Float:TEXT_DRAW_NAN), Float:y = (Float:TEXT_DRAW_NAN))
  1502. {
  1503. new
  1504. Style:id = TD_GetID(hash);
  1505. if (id != MAX_TEXT_DRAW_STYLES)
  1506. {
  1507. return TD_DisplayForAll(text, id, x, y);
  1508. }
  1509. return Text:INVALID_TEXT_DRAW;
  1510. }
  1511. /*----------------------------------------------------------------------------*-
  1512. Function:
  1513. Text:TD_DisplayNamed
  1514. Params:
  1515. text[] - Text to display.
  1516. style[] - Named style to display the text with.
  1517. Return:
  1518. -
  1519. Notes:
  1520. -
  1521. -*----------------------------------------------------------------------------*/
  1522. stock Text:TD_DisplayNamed(text[], style[], Float:x = (Float:TEXT_DRAW_NAN), Float:y = (Float:TEXT_DRAW_NAN))
  1523. {
  1524. return TD_DisplayHashed(text, bernstein(style), x, y);
  1525. }
  1526. stock Text:TD_DisplayNamedForPlayer(playerid, text[], style[], Float:x = (Float:TEXT_DRAW_NAN), Float:y = (Float:TEXT_DRAW_NAN))
  1527. {
  1528. return TD_DisplayHashedForPlayer(playerid, text, bernstein(style), x, y);
  1529. }
  1530. stock Text:TD_DisplayNamedForAll(text[], style[], Float:x = (Float:TEXT_DRAW_NAN), Float:y = (Float:TEXT_DRAW_NAN))
  1531. {
  1532. return TD_DisplayHashedForAll(text, bernstein(style), x, y);
  1533. }
  1534. /*----------------------------------------------------------------------------*-
  1535. Function:
  1536. TD_ShowForPlayer
  1537. Params:
  1538. playerid - Player to show the text to.
  1539. Text:textDraw - ID of the text to show.
  1540. Return:
  1541. -
  1542. Notes:
  1543. Now destroys any existing text draws using the same style in
  1544. the same place to avoid overlaps.
  1545. -*----------------------------------------------------------------------------*/
  1546. stock TD_ShowForPlayer(playerid, Text:textDraw)
  1547. {
  1548. if (Text:0 <= textDraw < Text:MAX_TEXT_DRAWS && !Bit_GetBit(YSI_g_sPlayerDraws[playerid], _:textDraw))
  1549. {
  1550. new
  1551. Text:real = YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REAL],
  1552. Style:style = YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_STYLE];
  1553. // This may have lost it's real rendering
  1554. if (real == Text:INVALID_TEXT_DRAW)
  1555. {
  1556. if (!YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_TEXT][0])
  1557. {
  1558. // There is no text to render.
  1559. return 0;
  1560. }
  1561. real = TD_Render(YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_TEXT], style, textDraw);
  1562. if (real == Text:INVALID_TEXT_DRAW)
  1563. {
  1564. return 0;
  1565. }
  1566. YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REAL] = real;
  1567. }
  1568. // Now show this for a player.
  1569. TextDrawShowForPlayer(playerid, real);
  1570. Bit_Let(YSI_g_sPlayerDraws[playerid], _:textDraw);
  1571. ++YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_LIFE];
  1572. new
  1573. time = YSI_g_sTDData[style][E_TD_DATA_TIME];
  1574. // TODO: Update.
  1575. /*if (YSI_g_sTDTimers[textDraw][playerid])
  1576. {
  1577. KillTimer(YSI_g_sTDTimers[textDraw][playerid]);
  1578. }*/
  1579. if (time)
  1580. {
  1581. //YSI_g_sTDTimers[textDraw][playerid] = SetTimerEx("TD_HideForPlayer", time, 0, "ii", playerid, _:textDraw);
  1582. TD_SetTimer(playerid, textDraw, time, YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REVISION]);
  1583. }
  1584. return 1;
  1585. }
  1586. return 0;
  1587. }
  1588. /*----------------------------------------------------------------------------*-
  1589. Function:
  1590. TD_HideForPlayer
  1591. Params:
  1592. playerid - Player to hide the text for.
  1593. Text:textDraw - Text to hide.
  1594. revision - The version of the text draw which existed when this was set.
  1595. Return:
  1596. -
  1597. Notes:
  1598. Public so the timer can call it to hide texts with a time set.
  1599. -*----------------------------------------------------------------------------*/
  1600. public TD_HideForPlayerPub(playerid, Text:textDraw, revision)
  1601. {
  1602. // Hide the TD only if it's not changed since last time (avoids ABA errors).
  1603. if (YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REVISION] == revision)
  1604. {
  1605. //if (playerid == INVALID_PLAYER_ID)
  1606. //{
  1607. // TD_HideForAll(textDraw);
  1608. //}
  1609. //else
  1610. //{
  1611. TD_HideForPlayer(playerid, textDraw);
  1612. //}
  1613. }
  1614. }
  1615. stock TD_HideForPlayer(playerid, Text:textDraw)
  1616. {
  1617. if (IsPlayerConnected(playerid))
  1618. {
  1619. if (Text:0 <= textDraw < Text:MAX_TEXT_DRAWS && Bit_GetBit(YSI_g_sPlayerDraws[playerid], _:textDraw))
  1620. {
  1621. // TODO: Update this to find the correct timer.
  1622. /*if (YSI_g_sTDTimers[textDraw][playerid])
  1623. {
  1624. KillTimer(YSI_g_sTDTimers[textDraw][playerid]);
  1625. }
  1626. YSI_g_sTDTimers[textDraw][playerid] = 0;*/
  1627. //YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_LIFE] = (count & 0x80000000) | ((count & 0x7FFFFFFF) - 1);
  1628. if (--YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_LIFE] == 0x80000000)
  1629. {
  1630. // No-one uses this any more, destroy it. Looking back on the
  1631. // code, this doesn't seem well implemented at all! Actually it
  1632. // is, ignore me. I forgot that you have to MANUALLY mark TDs
  1633. // as garbage for collection here.
  1634. TD_Destroy(Text:textDraw);
  1635. }
  1636. else
  1637. {
  1638. Bit_Vet(YSI_g_sPlayerDraws[playerid], _:textDraw);
  1639. TextDrawHideForPlayer(playerid, YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REAL]);
  1640. }
  1641. return 1;
  1642. }
  1643. }
  1644. return 0;
  1645. }
  1646. /*----------------------------------------------------------------------------*-
  1647. Function:
  1648. TD_ShowForAll
  1649. Params:
  1650. Text:textDraw - Text to show to all players.
  1651. Return:
  1652. -
  1653. Notes:
  1654. -
  1655. -*----------------------------------------------------------------------------*/
  1656. stock TD_ShowForAll(Text:textDraw)
  1657. {
  1658. if (Text:0 <= textDraw < Text:MAX_TEXT_DRAWS)
  1659. {
  1660. new
  1661. Text:real = YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REAL],
  1662. Style:style = YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_STYLE];
  1663. // This may have lost it's real rendering
  1664. if (real == Text:INVALID_TEXT_DRAW)
  1665. {
  1666. if (!YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_TEXT][0])
  1667. {
  1668. // There is no text to render.
  1669. return 0;
  1670. }
  1671. real = TD_Render(YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_TEXT], style, textDraw);
  1672. if (real == Text:INVALID_TEXT_DRAW)
  1673. {
  1674. return 0;
  1675. }
  1676. YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REAL] = real;
  1677. }
  1678. // Get the style information for showing this TD.
  1679. /*new
  1680. //index,
  1681. //count,
  1682. Float:x = YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_X],
  1683. Float:y = YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_Y],
  1684. Style:style = YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_STYLE],
  1685. time = YSI_g_sTDData[style][E_TD_DATA_TIME],
  1686. Text:next = YSI_g_sTDData[style][E_TD_DATA_USE],
  1687. Text:last = TEXT_DRAW_NO_NEXT,
  1688. Text:cur = TEXT_DRAW_NO_NEXT,
  1689. Text:thisLast = TEXT_DRAW_NO_NEXT;*/
  1690. /*while (next != TEXT_DRAW_NO_NEXT)
  1691. {
  1692. if (next == textDraw)
  1693. {
  1694. thisLast = last;
  1695. last = next;
  1696. next = YSI_g_sTDDisplay[next][E_TD_DISPLAY_NEXT];
  1697. }
  1698. else if (x == YSI_g_sTDDisplay[next][E_TD_DISPLAY_X] && y == YSI_g_sTDDisplay[next][E_TD_DISPLAY_Y])
  1699. {
  1700. // Hide existing text draws in the same location. This
  1701. // actually now seems like a bad idea!
  1702. count = YSI_g_sTDDisplay[next][E_TD_DISPLAY_LIFE];
  1703. cur = YSI_g_sTDDisplay[next][E_TD_DISPLAY_NEXT];
  1704. if (count & 0x80000000)
  1705. {
  1706. if (last == TEXT_DRAW_NO_NEXT)
  1707. {
  1708. YSI_g_sTDData[style][E_TD_DATA_USE] = cur;
  1709. }
  1710. else
  1711. {
  1712. YSI_g_sTDDisplay[last][E_TD_DISPLAY_NEXT] = cur;
  1713. }
  1714. YSI_g_sTDDisplay[next][E_TD_DISPLAY_NEXT] = YSI_g_sUnused;
  1715. YSI_g_sUnused = next;
  1716. new
  1717. Text:temp = YSI_g_sTDDisplay[next][E_TD_DISPLAY_REAL];
  1718. YSI_g_sTDDisplay[next][E_TD_DISPLAY_REAL] = Text:INVALID_TEXT_DRAW;
  1719. if (temp != Text:INVALID_TEXT_DRAW)
  1720. {
  1721. TextDrawDestroy(temp);
  1722. }
  1723. }
  1724. else
  1725. {
  1726. TextDrawHideForAll(YSI_g_sTDDisplay[next][E_TD_DISPLAY_REAL]);
  1727. last = next;
  1728. }
  1729. index = _:next / cellbits;
  1730. mod = 1 << (_:next % cellbits);
  1731. foreach (Player, playerid)
  1732. {
  1733. YSI_g_sPlayerDraws[playerid][index] &= Bit:mod;
  1734. }
  1735. next = cur;
  1736. }
  1737. else
  1738. {
  1739. last = next;
  1740. next = YSI_g_sTDDisplay[next][E_TD_DISPLAY_NEXT];
  1741. }
  1742. }*/
  1743. TextDrawShowForAll(real);
  1744. new
  1745. count = 0,
  1746. index = Bit_Slot(textDraw),
  1747. Bit:mod = Bit_Mask(textDraw),
  1748. time = YSI_g_sTDData[style][E_TD_DATA_TIME],
  1749. revision = YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REVISION];
  1750. foreach (Player, playerid)
  1751. {
  1752. YSI_g_sPlayerDraws[playerid][index] |= mod;
  1753. ++count;
  1754. // TODO: Update.
  1755. /*if (YSI_g_sTDTimers[textDraw][playerid])
  1756. {
  1757. KillTimer(YSI_g_sTDTimers[textDraw][playerid]);
  1758. }*/
  1759. //YSI_g_sTDTimers[textDraw][playerid] = SetTimerEx("TD_HideForPlayer", time, 0, "ii", playerid, _:textDraw);
  1760. if (time)
  1761. {
  1762. TD_SetTimer(playerid, textDraw, time, revision);
  1763. }
  1764. }
  1765. if (count)
  1766. {
  1767. // People can see it.
  1768. YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_LIFE] = (YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_LIFE] & 0x80000000) | count;
  1769. }
  1770. else
  1771. {
  1772. TD_TryDestroy(textDraw);
  1773. }
  1774. return 1;
  1775. //}
  1776. }
  1777. return 0;
  1778. }
  1779. /*----------------------------------------------------------------------------*-
  1780. Function:
  1781. TD_HideForAll
  1782. Params:
  1783. Text:textDraw - Text to hide from all players.
  1784. Return:
  1785. -
  1786. Notes:
  1787. Destroys the real text draw if marked for garbage collection.
  1788. -*----------------------------------------------------------------------------*/
  1789. stock TD_HideForAll(Text:textDraw)
  1790. {
  1791. if (Text:0 <= textDraw < Text:MAX_TEXT_DRAWS)
  1792. {
  1793. new
  1794. Text:real = YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REAL];
  1795. if (!TD_TryDestroy(textDraw))
  1796. {
  1797. if (real != Text:INVALID_TEXT_DRAW)
  1798. {
  1799. YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_LIFE] = 0;
  1800. new
  1801. index = Bit_Slot(textDraw),
  1802. Bit:inv = ~Bit_Mask(textDraw);//,
  1803. //Bit:inv = ~mod;
  1804. // Hide it for all players but don't destroy it.
  1805. TextDrawHideForAll(real);
  1806. ++YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_REVISION];
  1807. foreach (Player, playerid)
  1808. {
  1809. //if (YSI_g_sPlayerDraws[playerid][index] & mod)
  1810. //{
  1811. // Need to sort out the timers.
  1812. // TODO: Update
  1813. /*if (YSI_g_sTDTimers[textDraw][playerid])
  1814. {
  1815. KillTimer(YSI_g_sTDTimers[textDraw][playerid]);
  1816. YSI_g_sTDTimers[textDraw][playerid] = 0;
  1817. }*/
  1818. YSI_g_sPlayerDraws[playerid][index] &= inv;
  1819. //}
  1820. }
  1821. }
  1822. }
  1823. }
  1824. return 1;
  1825. }
  1826. /*----------------------------------------------------------------------------*-
  1827. Function:
  1828. TD_OnPlayerDisconnect
  1829. Params:
  1830. playerid - Player who left.
  1831. reason - Why they left.
  1832. Return:
  1833. -
  1834. Notes:
  1835. Required to fix bugs in the textdraw system by hiding all
  1836. visible ones.
  1837. -*----------------------------------------------------------------------------*/
  1838. public OnPlayerDisconnect(playerid, reason)
  1839. {
  1840. for (new i = 0; i < bits<MAX_TEXT_DRAWS>; i++)
  1841. {
  1842. new
  1843. Bit:s = YSI_g_sPlayerDraws[playerid][i],
  1844. j = 0,
  1845. ix = i << 5;
  1846. while (s)
  1847. {
  1848. // Get rid of data for textdraws which this player can see. We
  1849. // don't need to actually hide the textdraw as the player has left.
  1850. if (s & Bit:1)
  1851. {
  1852. new
  1853. Text:textDraw = Text:(ix + j);
  1854. /*if (YSI_g_sTDTimers[textDraw][playerid])
  1855. {
  1856. // TODO: Update.
  1857. KillTimer(YSI_g_sTDTimers[textDraw][playerid]);
  1858. YSI_g_sTDTimers[textDraw][playerid] = 0;
  1859. }*/
  1860. if (--YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_LIFE] == 0x80000000)
  1861. {
  1862. TD_Destroy(textDraw);
  1863. }
  1864. //TD_TryDestroy(textDraw);
  1865. }
  1866. s >>>= Bit:1;
  1867. ++j;
  1868. }
  1869. YSI_g_sPlayerDraws[playerid][i] = Bit:0;
  1870. }
  1871. ALS_CALL<PlayerDisconnect>
  1872. }
  1873. #if defined _ALS_OnPlayerDisconnect
  1874. #undef OnPlayerDisconnect
  1875. #else
  1876. #define _ALS_OnPlayerDisconnect
  1877. #endif
  1878. #define OnPlayerDisconnect TD_OnPlayerDisconnect
  1879. ALS_FORWARD<PlayerDisconnect>
  1880. /*----------------------------------------------------------------------------*-
  1881. Function:
  1882. TD_Garbage
  1883. Params:
  1884. Text:textDraw - Text to mark as garbage.
  1885. Return:
  1886. -
  1887. Notes:
  1888. Tells the system to remove a text draw when no-one can see it
  1889. anymore to free up text draw slots.
  1890. -*----------------------------------------------------------------------------*/
  1891. stock TD_Garbage(Text:textDraw)
  1892. {
  1893. if (Text:0 <= textDraw < Text:MAX_TEXT_DRAWS)
  1894. {
  1895. if (YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_LIFE] & 0x7FFFFFFF)
  1896. {
  1897. // Players can still see it.
  1898. YSI_g_sTDDisplay[textDraw][E_TD_DISPLAY_LIFE] |= 0x80000000;
  1899. }
  1900. else
  1901. {
  1902. // No-one can see it.
  1903. TD_Destroy(textDraw);
  1904. }
  1905. }
  1906. }
  1907. #undef ALS_PREFIX
  1908. //#endif