HLMOD.HU Forrás Megtekintés - www.hlmod.hu
  1.  
  2. /* Map Spawns Editor v1.0 update [2006-10-23]
  3. http://forums.alliedmods.net/showthread.php?t=43660
  4.  
  5.   This plugin let you ( add & del & edit ) map spawns absolute easy.
  6.  
  7. What's for::
  8.  * A lot of map have spawndeath & bad position & less spawns problem I know since I has made a server 5 months.
  9.   How can we fix this? I use some tools todo this but it hard use and do something when you are playing the game.
  10.   I got the way to do this, so I made this plugin.
  11.  
  12.  * How easy?
  13.   1, One plugin and use one menu you can do all thing.
  14.   2, Edit spawns and shange spawns angle at anytime without restart server or reload map just use save function.
  15.   3, Add & Del spawns just reload map once (you can Del all spawns if you want)
  16. */
  17.  
  18. /* Requirements::
  19.   AMX Mod X 1.76a or greater
  20.   Engine module
  21. */
  22.  
  23. /* Install Instructions::
  24.  * put the lang file Map_Spawns_Editor.amxx to (addons\amxmodx\plugins) folder
  25.  * put the lang file map_spawns_editor.txt to (addons\amxmodx\data\lang) folder
  26. */
  27.  
  28. /* Description::
  29.   1,Load the map which need to be edit spawns.
  30.   2,Join server with ADMIN_BAN and bind a key with amx_editor_menu command.
  31.   3,Type amx_spawn_editor 1 in console to enable editor function
  32.   4,Push your binded key to open editor menu.(all function in menu)
  33.   5,Now Add & Del & Edit use menu.(change angle and del spawn you need aim spawn what is need to be made)
  34.   6,Finally, select <save all spawns> in menu when you finished and the changes will be activated.
  35.   NOTICE: If your (Editor Spawns) diff. to (Origina Spawns) that the map needs to be reloaded once to activate your changes.
  36. */
  37.  
  38. /* Console Commands::
  39.  * amx_spawn_editor 1/0 // Enable & Disable Editor Function
  40.  * amx_editor_menu // open Editor Menu
  41. */
  42.  
  43. /* Change Log::
  44.  * [2006-10-23] v1.0
  45.   Rewrite all code, it's almost a new one.
  46.   Fixed the Del spawns can not be less than orgign limit.
  47.   Added change spawn vangle left&right function.
  48.   Added easily create above player spawn function.
  49.   Added auto create (spawns) folder function if it's not exist.
  50.   Added multi-lingual support
  51.   Added Cvar map_spawns record spawns lets HLSW or Server Tools can see how many spawns in that map.
  52.  * [2006-08-23] First release. v0.5 [98 downloaded]
  53.   it works but have more bad code
  54. */
  55.  
  56. /* Credits:: help & some code from them
  57.  * FreeCode, BAILOPAN, VEN, oneofthedragon
  58.  * and more...
  59. */
  60.  
  61. /* Screenshots::
  62.  
  63. */
  64.  
  65. #include <amxmodx>
  66. #include <amxmisc>
  67. #include <engine>
  68.  
  69. #define REQUIRED_ADMIN_LEVEL ADMIN_BAN // ADMIN_LEVEL_C
  70.  
  71. #define PLUGINNAME "Map Spawns Editor"
  72. #define VERSION "1.0.16"
  73. #define AUTHOR "iG_os"
  74.  
  75. // CS default MDL and SPR
  76. #define T_MDL "models/player/leet/leet.mdl"
  77. #define CT_MDL "models/player/gign/gign.mdl"
  78. #define LINE_SPR "sprites/laserbeam.spr"
  79.  
  80. #define CHECKTIMER 0.8
  81. #define CHECKTASKID 666
  82. #define RESETENTITYTASKID 777
  83. #define SAFEp2p 85 // point to point safe distance
  84. #define SAFEp2w 40 // point to wall safe distance
  85.  
  86. #define EDIT_CLASSNAME "Map_Spawns_Editor"
  87.  
  88. #define SPAWN_PRESENT_OFFSET 10
  89. #define SPAWN_ABOVE_OFFSET 115
  90.  
  91. // store filename
  92. new g_SpawnFile[256], g_DieFile[256], g_EntFile[256]
  93.  
  94. new g_MainMenuID = -1 // Menu Handel ID
  95.  
  96. new bool:g_DeathCheck_end = false
  97. new bool:g_LoadSuccessed = false
  98. new bool:g_LoadInit = false
  99.  
  100. new bool:g_CheckDistance = true
  101.  
  102. new bool:g_AbovePlayer = false
  103. new g_OffSet = SPAWN_PRESENT_OFFSET
  104.  
  105. new g_Editing
  106. new g_SpawnT, g_EditT
  107. new g_SpawnCT,g_EditCT
  108. new Laser_Spr
  109. new g_BeamColors[4][3]={{255,0,0},{0,255,0},{200,200,0},{0,0,255}}
  110.  
  111.  
  112. public plugin_init()
  113. {
  114. register_plugin(PLUGINNAME, VERSION, AUTHOR)
  115. register_dictionary("map_spawns_editor.txt")
  116.  
  117. g_LoadInit = true // disabled pfn_keyvalue using
  118.  
  119. Spawns_Count()
  120. new string[16]
  121. format(string,15,"T(%d) CT(%d)",g_SpawnT,g_SpawnCT)
  122. register_cvar("map_spawns",string,FCVAR_SERVER) // spawns info for HLSW display
  123.  
  124. register_event("TextMsg", "event_restartgame", "a", "2&#Game_C","2&#Game_w")
  125. register_event("DeathMsg", "event_death", "a")
  126. register_event("HLTV", "event_newround", "a", "1=0", "2=0")
  127.  
  128. register_clcmd("amx_spawn_editor", "editor_onoff", REQUIRED_ADMIN_LEVEL, "- 1/0 switch editor function on/off")
  129. register_clcmd("amx_editor_menu", "editor_menu", REQUIRED_ADMIN_LEVEL, "- open editor menu")
  130.  
  131. }
  132.  
  133.  
  134. public editor_onoff(id,level,cid)
  135. {
  136. if (!cmd_access(id,level,cid,1)) return PLUGIN_HANDLED
  137.  
  138. if (g_Editing && g_Editing!=id){
  139. client_print(id,print_chat,"* %L",id,"MSG_ALREADY_INUSE")
  140. return PLUGIN_HANDLED
  141. }
  142.  
  143. new arg[2]
  144. read_argv(1,arg,2)
  145. if (equal(arg,"1",1) && !g_Editing){
  146. g_Editing = id
  147. Clear_AllEdit(0)
  148. Load_SpawnFlie(0)
  149. Spawns_To_Edit()
  150. client_print(0,print_chat,">> %L - %L",id,"MENU_TITLE",id,"ON")
  151. }else if (equal(arg,"0",1)){
  152. g_Editing = 0
  153. Clear_AllEdit(0)
  154. if (task_exists(id+CHECKTASKID)) remove_task(id+CHECKTASKID)
  155. client_print(0,print_chat,">> %L - %L",id,"MENU_TITLE",id,"OFF")
  156. }
  157. return PLUGIN_HANDLED
  158. }
  159.  
  160.  
  161. public editor_menu(id,level,cid)
  162. {
  163. if (!cmd_access(id,level,cid,1))
  164. return PLUGIN_HANDLED
  165.  
  166. if (!g_Editing){
  167. client_print(id,print_chat,"* %L",id,"MSG_FUNCTION_DISABLED")
  168. return PLUGIN_HANDLED
  169. }
  170.  
  171. if (g_Editing!=id){
  172. client_print(id,print_chat,"* %L",id,"MSG_ALREADY_INUSE")
  173. return PLUGIN_HANDLED
  174. }
  175.  
  176. new tempString[101]
  177. format(tempString,100,"%L",id,"MENU_TITLE")
  178. g_MainMenuID = menu_create(tempString, "m_MainHandler")
  179. new callbackMenu = menu_makecallback("c_Main")
  180.  
  181. // page 1
  182. menu_additem(g_MainMenuID, "[Spawns Info]","1", 1, callbackMenu)
  183. menu_addblank(g_MainMenuID, 0)
  184.  
  185. menu_additem(g_MainMenuID, "[Add spawn locate: present/above player]","2", 0, callbackMenu)
  186. format(tempString,100,"%L",id,"MENU_ADD_SPAWN","T")
  187. menu_additem(g_MainMenuID, tempString,"3", 0, callbackMenu)
  188. format(tempString,100,"%L",id,"MENU_ADD_SPAWN","CT")
  189. menu_additem(g_MainMenuID, tempString,"4", 0, callbackMenu)
  190. menu_addblank(g_MainMenuID, 0)
  191.  
  192. format(tempString,100,"\y%L",id,"MENU_TURN_LEFT")
  193. menu_additem(g_MainMenuID, tempString,"5", 0, callbackMenu)
  194. format(tempString,100,"\y%L",id,"MENU_TURN_RIGHT")
  195. menu_additem(g_MainMenuID, tempString,"6", 0, callbackMenu)
  196. menu_addblank(g_MainMenuID, 0)
  197.  
  198. format(tempString,100,"%L",id,"MENU_SAVE_ALL_SPAWNS")
  199. menu_additem(g_MainMenuID, tempString,"7", 0, callbackMenu)
  200. menu_addblank(g_MainMenuID, 0)
  201. // page 1 end
  202.  
  203. // page 2
  204. menu_additem(g_MainMenuID, "[Spawns Info]","11", 1, callbackMenu)
  205. menu_addblank(g_MainMenuID, 0)
  206.  
  207. menu_additem(g_MainMenuID, "[Safe range check on/off]","12", 0, callbackMenu)
  208. format(tempString,100,"%L",id,"MENU_CLEAR_SPAWN")
  209. menu_additem(g_MainMenuID, tempString,"13", 0, callbackMenu)
  210. menu_addblank(g_MainMenuID, 0)
  211.  
  212. format(tempString,100,"%L",id,"MENU_CLEAR_ALL_T_SPAWNS")
  213. menu_additem(g_MainMenuID, tempString,"14", 0, callbackMenu)
  214. format(tempString,100,"%L",id,"MENU_CLEAR_ALL_CT_SPAWNS")
  215. menu_additem(g_MainMenuID, tempString,"15", 0, callbackMenu)
  216.  
  217. format(tempString,100,"%L",id,"MENU_DEL_SPAWNS_FILE")
  218. menu_additem(g_MainMenuID, tempString,"16", 0, callbackMenu)
  219.  
  220. format(tempString,100,"%L",id,"MENU_EXPORT_FOR_RIPENT")
  221. menu_additem(g_MainMenuID, tempString,"17", 0, callbackMenu)
  222. menu_addblank(g_MainMenuID, 0)
  223. // page 2 end
  224.  
  225. format(tempString,100,"%L",id,"MENU_EXIT")
  226. menu_setprop(g_MainMenuID, MPROP_EXITNAME, tempString)
  227. format(tempString,100,"%L",id,"MENU_NEXT")
  228. menu_setprop(g_MainMenuID, MPROP_NEXTNAME, tempString)
  229. format(tempString,100,"%L",id,"MENU_BACK")
  230. menu_setprop(g_MainMenuID, MPROP_BACKNAME, tempString)
  231.  
  232. menu_setprop(g_MainMenuID, MPROP_EXIT, MEXIT_ALL)
  233. menu_display (id,g_MainMenuID,0)
  234.  
  235. client_cmd(id,"spk buttons/button9")
  236. set_task(CHECKTIMER,"check_Task",id+CHECKTASKID,_,_,"b")
  237.  
  238. return PLUGIN_HANDLED
  239. }
  240.  
  241. public c_Main(id, menu, item)
  242. {
  243. if (item < 0) return PLUGIN_CONTINUE
  244.  
  245. new cmd[6], fItem[256], iName[64]
  246. new access, callback
  247. menu_item_getinfo(menu, item, access, cmd, 5, iName, 63, callback)
  248. new num = str_to_num(cmd)
  249.  
  250. if (num==1 || num==11){
  251. if (g_EditT!=g_SpawnT || g_EditCT!=g_SpawnCT)
  252. format(fItem,255,"%L ( T=%d + CT=%d ) ^n0.\y %L \r( T=%d + CT=%d ) ^n>> %L", id, "MENU_ORIGIN_SPAWNS",g_SpawnT,g_SpawnCT, id,"MENU_EDIT_SPAWNS", g_EditT,g_EditCT, id,"MENU_NOTICE_SAVE")
  253. else format(fItem,255,"%L ( T=%d + CT=%d ) ^n0.\y %L ( T=%d + CT=%d )", id, "MENU_ORIGIN_SPAWNS",g_SpawnT,g_SpawnCT, id,"MENU_EDIT_SPAWNS", g_EditT,g_EditCT)
  254. menu_item_setname(menu, item, fItem )
  255. return ITEM_DISABLED
  256. }
  257. switch (num){
  258. case 2:{
  259. if (g_AbovePlayer)
  260. format(fItem,255,"\y%L ->\r %L",id,"MENU_ADD_LOCATION",id,"MENU_LOCATION_ABOVE")
  261. else format(fItem,255,"\y%L ->\r %L",id,"MENU_ADD_LOCATION",id,"MENU_LOCATION_CURRENT")
  262. menu_item_setname(menu, item, fItem )
  263. }
  264. case 12:{
  265. if (g_CheckDistance)
  266. format(fItem,255,"\y%L ->\r %L",id,"MENU_SAFE_CHECK",id,"ON")
  267. else format(fItem,255,"\y%L ->\r %L",id,"MENU_SAFE_CHECK",id,"OFF")
  268. menu_item_setname(menu, item, fItem )
  269. }
  270. }
  271. return ITEM_ENABLED
  272. }
  273.  
  274. public m_MainHandler(id, menu, item)
  275. {
  276. if (item==MENU_EXIT || !g_Editing){
  277. if (task_exists(id+CHECKTASKID)) remove_task(id+CHECKTASKID)
  278. menu_destroy(g_MainMenuID)
  279. return PLUGIN_HANDLED
  280. }
  281.  
  282. new cmd[6], iName[64]
  283. new access, callback
  284. menu_item_getinfo(menu, item, access, cmd,5, iName, 63, callback)
  285. new iChoice = str_to_num(cmd)
  286.  
  287. switch(iChoice)
  288. {
  289. case 2:{ // Location Set
  290. if (g_AbovePlayer){
  291. g_OffSet = SPAWN_PRESENT_OFFSET
  292. g_AbovePlayer = false
  293. }else{
  294. g_OffSet = SPAWN_ABOVE_OFFSET
  295. g_AbovePlayer = true
  296. }
  297. client_cmd(id,"spk buttons/button3")
  298. }
  299. case 3:{ // Add T Spawn
  300. if (g_CheckDistance && !SafeRangeCheck(id,g_OffSet)){
  301. client_cmd(id,"spk buttons/button2")
  302. client_print(0,print_chat,">> %L",id,"MSG_CHECK_FAULT")
  303. }
  304. else if (CreateEditEntity(1,id,g_OffSet)==1){
  305. g_EditT++
  306. client_cmd(id,"spk buttons/button9")
  307. client_print(0,print_chat,">> %L",id,"MENU_ADD_SPAWN","T")
  308. }
  309. }
  310. case 4:{ // Add CT Spawn
  311. if (g_CheckDistance && !SafeRangeCheck(id,g_OffSet)){
  312. client_cmd(id,"spk buttons/button2")
  313. client_print(0,print_chat,">> %L",id,"MSG_CHECK_FAULT")
  314. }
  315. else if (CreateEditEntity(2,id,g_OffSet)==2){
  316. g_EditCT++
  317. client_cmd(id,"spk buttons/button9")
  318. client_print(0,print_chat,">> %L",id,"MENU_ADD_SPAWN","CT")
  319. }
  320. }
  321. case 5:{ // Spawn Turn Left
  322. new entity = Get_Edit_Point_By_Aim(id)
  323. if (entity && is_valid_ent(entity)){
  324. Entity_Turn_angle(entity,10)
  325. client_cmd(id,"spk buttons/blip1")
  326. }else{
  327. client_cmd(id,"spk buttons/button2")
  328. client_print(0,print_chat,">> %L",id,"ERROR_POINT_NOTFOUND")
  329. }
  330. }
  331. case 6:{ // Spawn Turn Right
  332. new entity = Get_Edit_Point_By_Aim(id)
  333. if (entity && is_valid_ent(entity)){
  334. Entity_Turn_angle(entity,-10)
  335. client_cmd(id,"spk buttons/blip1")
  336. }else{
  337. client_cmd(id,"spk buttons/button2")
  338. client_print(0,print_chat,">> %L",id,"ERROR_POINT_NOTFOUND")
  339. }
  340. }
  341. case 7:{ // Save All Spawn To File
  342. if (Save_SpawnsFile()){
  343. Load_SpawnFlie(0)
  344. client_cmd(id,"spk buttons/blip2")
  345. client_print(0,print_chat,">> %L (T=%d,CT=%d)",id,"MSG_SAVE_SPAWNSFLIE",g_EditT,g_EditCT)
  346. }else
  347. client_print(0,print_chat,">> %L",id,"ERROR_SAVE_SPAWNSFLIE")
  348. }
  349. case 12:{ // Safe Range Check
  350. g_CheckDistance = g_CheckDistance ? false:true
  351. client_cmd(id,"spk buttons/button3")
  352. }
  353. case 13:{ // Clear a Spawn
  354. new entity = Get_Edit_Point_By_Aim(id)
  355. if (entity && is_valid_ent(entity)){
  356. new team = entity_get_int(entity,EV_INT_iuser2)
  357. remove_entity(entity)
  358. client_cmd(id,"spk buttons/button3")
  359. if (team==1){
  360. g_EditT--
  361. client_print(0,print_chat,">> %L",id,"MSG_CLEAR_SPAWN","T")
  362. }else{
  363. g_EditCT--
  364. client_print(0,print_chat,">> %L",id,"MSG_CLEAR_SPAWN","CT")
  365. }
  366. }else{
  367. client_cmd(id,"spk buttons/button2")
  368. client_print(0,print_chat,">> %L",id,"ERROR_POINT_NOTFOUND")
  369. }
  370. }
  371. case 14:{ // Clear All T Spawn
  372. Clear_AllEdit(1)
  373. client_cmd(id,"spk buttons/blip2")
  374. client_print(0,print_chat,">> %L",id,"MENU_CLEAR_ALL_T_SPAWNS")
  375. }
  376. case 15:{ // Clear All CT Spawn
  377. Clear_AllEdit(2)
  378. client_cmd(id,"spk buttons/blip2")
  379. client_print(0,print_chat,">> %L",id,"MENU_CLEAR_ALL_CT_SPAWNS")
  380. }
  381. case 16:{ // Del Spawns Flie
  382. if (file_exists(g_SpawnFile)){
  383. delete_file(g_SpawnFile)
  384. client_cmd(id,"spk buttons/blip2")
  385. client_print(0,print_chat,">> %L",id,"MSG_DEL_SPAWNSFILE")
  386. }
  387. }
  388. case 17:{ // Expotr Spawn To ENT Format
  389. if (Export_RipentFormatFile()){
  390. client_cmd(id,"spk buttons/blip2")
  391. client_print(0,print_chat,">> %L [%s] (T=%d,CT=%d)",id,"MSG_EXOPRT_SPAWNSFLIE",g_EntFile,g_EditT,g_EditCT)
  392. }
  393. }
  394. }
  395.  
  396. if (iChoice>=11 && iChoice<=17) // go back to second page is using
  397. menu_display (id, g_MainMenuID, 1)
  398. else menu_display (id, g_MainMenuID, 0)
  399. return PLUGIN_CONTINUE
  400. }
  401.  
  402.  
  403. public plugin_precache()
  404. {
  405. new configdir[128]
  406. get_configsdir(configdir, 127 )
  407. new spawndir[256]
  408. format(spawndir,255,"%s/spawns",configdir)
  409. if (!dir_exists(spawndir)){
  410. if (mkdir(spawndir)==0){ // Create a dir,if it's not exist
  411. log_amx("Create [%s] dir successfully finished.",spawndir)
  412. }else{
  413. log_error(AMX_ERR_NOTFOUND,"Couldn't create [%s] dir,plugin stoped.",spawndir)
  414. pause("ad")
  415. return PLUGIN_CONTINUE
  416. }
  417. }
  418.  
  419. precache_model(T_MDL)
  420. precache_model(CT_MDL)
  421. Laser_Spr = precache_model(LINE_SPR)
  422.  
  423. new MapName[32]
  424. get_mapname(MapName, 31)
  425. //store spawns point data in this file
  426. format(g_SpawnFile, 255, "%s/%s_spawns.cfg",spawndir, MapName)
  427. //when restart game some bad spawn point will make user die,store data in this file,it's useful.
  428. format(g_DieFile, 255, "%s/%s_spawns_die.cfg",spawndir, MapName)
  429. //export spawns data to this file for ripent.exe format,it's useful for import to bsp for ripent.exe
  430. format(g_EntFile, 255, "%s/%s_ent.txt",spawndir, MapName)
  431.  
  432. if (Load_SpawnFlie(1)) //load spawn file and create player spawn points
  433. g_LoadSuccessed = true
  434. else
  435. g_LoadSuccessed = false
  436.  
  437. return PLUGIN_CONTINUE
  438. }
  439.  
  440. //load spawns from file, Return 0 when didn't load anything.
  441. stock Load_SpawnFlie(type) //createEntity = 1 create an entity when load a point
  442. {
  443. if (file_exists(g_SpawnFile))
  444. {
  445. new ent_T, ent_CT
  446. new Data[128], len, line = 0
  447. new team[8], p_origin[3][8], p_angles[3][8]
  448. new Float:origin[3], Float:angles[3]
  449.  
  450. while((line = read_file(g_SpawnFile , line , Data , 127 , len) ) != 0 )
  451. {
  452. if (strlen(Data)<2) continue
  453.  
  454. parse(Data, team,7, p_origin[0],7, p_origin[1],7, p_origin[2],7, p_angles[0],7, p_angles[1],7, p_angles[2],7)
  455.  
  456. origin[0] = str_to_float(p_origin[0]); origin[1] = str_to_float(p_origin[1]); origin[2] = str_to_float(p_origin[2]);
  457. angles[0] = str_to_float(p_angles[0]); angles[1] = str_to_float(p_angles[1]); angles[2] = str_to_float(p_angles[2]);
  458.  
  459. if (equali(team,"T")){
  460. if (type==1) ent_T = create_entity("info_player_deathmatch")
  461. else ent_T = find_ent_by_class(ent_T, "info_player_deathmatch")
  462. if (ent_T>0){
  463. entity_set_int(ent_T,EV_INT_iuser1,1) // mark that create by map spawns editor
  464. entity_set_origin(ent_T,origin)
  465. entity_set_vector(ent_T, EV_VEC_angles, angles)
  466. }
  467. }
  468. else if (equali(team,"CT")){
  469. if (type==1) ent_CT = create_entity("info_player_start")
  470. else ent_CT = find_ent_by_class(ent_CT, "info_player_start")
  471. if (ent_CT>0){
  472. entity_set_int(ent_CT,EV_INT_iuser1,1) // mark that create by map spawns editor
  473. entity_set_origin(ent_CT,origin)
  474. entity_set_vector(ent_CT, EV_VEC_angles, angles)
  475. }
  476. }
  477. }
  478. return 1
  479. }
  480. return 0
  481. }
  482.  
  483. // pfn_keyvalue..Execure after plugin_precache and before plugin_init
  484. public pfn_keyvalue(entid)
  485. { // when load custom spawns file successed,we are del all spawns by map originate create
  486. if (g_LoadSuccessed && !g_LoadInit){
  487. new classname[32], key[32], value[32]
  488. copy_keyvalue(classname, 31, key, 31, value, 31)
  489.  
  490. if (equal(classname, "info_player_deathmatch") || equal(classname, "info_player_start")){
  491. if (is_valid_ent(entid) && entity_get_int(entid,EV_INT_iuser1)!=1) //filter out custom spawns
  492. remove_entity(entid)
  493. }
  494. }
  495. return PLUGIN_CONTINUE
  496. }
  497.  
  498.  
  499. public event_restartgame()
  500. {
  501. if (g_Editing && file_exists(g_DieFile))
  502. delete_file(g_DieFile)
  503.  
  504. g_DeathCheck_end = false
  505.  
  506. if (g_Editing){
  507. Clear_AllEdit(0)
  508. Load_SpawnFlie(0)
  509. Spawns_To_Edit()
  510. }
  511. return PLUGIN_CONTINUE
  512. }
  513.  
  514. // Remove & save bad spawn point where force user die.
  515. public event_death()
  516. {
  517. if (!g_DeathCheck_end){
  518. new string[12]
  519. read_data(4,string,11)
  520. if (equal(string,"worldspawn")){
  521. new id = read_data(2)
  522. if (g_Editing){
  523. new entList[1],team
  524. find_sphere_class(id,EDIT_CLASSNAME, 30.0, entList, 1)
  525. if (entList[0]){
  526. team = entity_get_int(entList[0],EV_INT_iuser2) // team mark
  527. if (team==1){
  528. client_print(0,print_chat,">> %L",id,"MSG_AUTO_REMOVE_SPAWN","T")
  529. g_EditT--
  530. }else{
  531. client_print(0,print_chat,">> %L",id,"MSG_AUTO_REMOVE_SPAWN","CT")
  532. g_EditCT--
  533. }
  534. remove_entity(entList[0])
  535. return PLUGIN_CONTINUE
  536. }
  537. }else{
  538. new team = get_user_team(id)
  539. if (team==1) Point_WriteToFlie(g_DieFile,1,id,1)
  540. else if (team==2) Point_WriteToFlie(g_DieFile,2,id,1)
  541. }
  542. }
  543. }
  544. return PLUGIN_CONTINUE
  545. }
  546.  
  547. public event_newround()
  548. set_task(3.0,"deathCheck_end")
  549.  
  550. public deathCheck_end()
  551. g_DeathCheck_end = true
  552.  
  553.  
  554. // create a edit point
  555. stock CreateEditEntity(team,iEnt,offset)
  556. {
  557. new Float:fOrigin[3],Float:fAngles[3]
  558. entity_get_vector(iEnt, EV_VEC_origin, fOrigin)
  559. entity_get_vector(iEnt, EV_VEC_angles, fAngles)
  560. fOrigin[2] += float(offset) //offset Z
  561.  
  562. new entity = create_entity("info_target")
  563. if (entity){
  564. entity_set_string(entity, EV_SZ_classname, EDIT_CLASSNAME)
  565. entity_set_model(entity,(team==1) ? T_MDL:CT_MDL)
  566. entity_set_origin(entity, fOrigin)
  567. entity_set_vector(entity, EV_VEC_angles, fAngles)
  568. entity_set_int(entity, EV_INT_sequence, 4)
  569. entity_set_int(entity,EV_INT_iuser2,team) // team mark
  570. return team
  571. }
  572. return 0
  573. }
  574.  
  575. // clear up all edit points
  576. stock Clear_AllEdit(team){
  577. new entity
  578. switch (team){
  579. case 0:{
  580. while ((entity = find_ent_by_class(entity, EDIT_CLASSNAME)))
  581. remove_entity(entity)
  582. g_EditT = 0
  583. g_EditCT = 0
  584. }
  585. case 1:{
  586. while ((entity = find_ent_by_class(entity, EDIT_CLASSNAME)))
  587. if (entity_get_int(entity,EV_INT_iuser2)==1)
  588. remove_entity(entity)
  589. g_EditT = 0
  590. }
  591. case 2:{
  592. while ((entity = find_ent_by_class(entity, EDIT_CLASSNAME)))
  593. if (entity_get_int(entity,EV_INT_iuser2)==2)
  594. remove_entity(entity)
  595. g_EditCT = 0
  596. }
  597. }
  598. }
  599.  
  600. // convert origin spawns to edit points
  601. stock Spawns_To_Edit()
  602. {
  603. new entity
  604. g_EditT = 0
  605. while ((entity = find_ent_by_class(entity, "info_player_deathmatch"))){
  606. CreateEditEntity(1,entity,0)
  607. g_EditT++
  608. }
  609. entity = 0
  610. g_EditCT = 0
  611. while ((entity = find_ent_by_class(entity, "info_player_start"))){
  612. CreateEditEntity(2,entity,0)
  613. g_EditCT++
  614. }
  615. }
  616.  
  617. stock Spawns_Count()
  618. {
  619. new entity
  620. g_SpawnT = 0
  621. while ((entity = find_ent_by_class(entity, "info_player_deathmatch")))
  622. g_SpawnT++
  623.  
  624. entity = 0
  625. g_SpawnCT = 0
  626. while ((entity = find_ent_by_class(entity, "info_player_start")))
  627. g_SpawnCT++
  628. }
  629.  
  630. public check_Task(taskid){
  631. SafeRangeCheck(taskid-CHECKTASKID,SPAWN_PRESENT_OFFSET)
  632. Get_Edit_Point_By_Aim(taskid-CHECKTASKID)
  633. }
  634.  
  635. // reset entity sequence
  636. public reset_entity_stats(param){
  637. new entity = param - RESETENTITYTASKID
  638. if (is_valid_ent(entity)){
  639. entity_set_float(entity, EV_FL_animtime, 0.0)
  640. entity_set_float(entity, EV_FL_framerate, 0.0)
  641. entity_set_int(entity, EV_INT_sequence, 4)
  642. }
  643. }
  644.  
  645. // set entity vangle[1]+turn
  646. stock Entity_Turn_angle(entity,turn){
  647. if (is_valid_ent(entity)){
  648. new Float:fAngles[3]
  649. entity_get_vector(entity, EV_VEC_angles, fAngles)
  650. fAngles[1] += turn
  651. if (fAngles[1]>=360) fAngles[1] -= 360
  652. if (fAngles[1]<0) fAngles[1] += 360
  653. entity_set_vector(entity, EV_VEC_angles, fAngles)
  654. }
  655. }
  656.  
  657. // check edit point or wall distance to id
  658. stock SafeRangeCheck(id,offset)
  659. {
  660. new safepostion = 1
  661. new Float:fOrigin[3],Float:fAngles[3],Float:inFrontPoint[3],Float:HitPoint[3]
  662. entity_get_vector(id, EV_VEC_origin, fOrigin)
  663. fOrigin[2] += offset // hight offset,same as Edit Point offset
  664. entity_get_vector(id, EV_VEC_angles, fAngles)
  665.  
  666. for (new i=0;i<360;i+=10)
  667. {
  668. fAngles[1] = float(i)
  669. // get the id infront point for trace_line
  670. Vector_By_Angle(fOrigin,fAngles, SAFEp2w * 2.0, 1, inFrontPoint)
  671.  
  672. // check id nearby wall
  673. trace_line(-1,fOrigin,inFrontPoint,HitPoint)
  674. new distance = floatround(vector_distance(fOrigin, HitPoint))
  675.  
  676. if (distance<SAFEp2w){ // unsafe distance to wall
  677. Make_TE_BEAMPOINTS(id,0,fOrigin,HitPoint,2,255)
  678. safepostion = 0
  679. }
  680. else if (distance < SAFEp2w * 1.5)
  681. Make_TE_BEAMPOINTS(id,2,fOrigin,HitPoint,2,255)
  682. }
  683.  
  684. // check id nearby Edit Points
  685. new entList[10],Float:vDistance
  686. new Float:entity_origin[3]
  687. find_sphere_class(0,EDIT_CLASSNAME, SAFEp2p * 1.5, entList, 9, fOrigin)
  688. for(new i=0;i<10;i++){
  689. if (entList[i]){
  690. entity_get_vector(entList[i], EV_VEC_origin, entity_origin)
  691. vDistance = vector_distance(fOrigin,entity_origin)
  692. if (vDistance < SAFEp2p){ // unsafe location to Edit Points
  693. Make_TE_BEAMPOINTS(id,0,fOrigin,entity_origin,5,255)
  694. entity_set_int(entList[i], EV_INT_sequence, 64)
  695. safepostion = 0
  696. if (task_exists(entList[i]+RESETENTITYTASKID))
  697. remove_task(entList[i]+RESETENTITYTASKID)
  698. set_task(CHECKTIMER+0.1,"reset_entity_stats",entList[i]+RESETENTITYTASKID)
  699. } else Make_TE_BEAMPOINTS(id,1,fOrigin,entity_origin,5,255)
  700. }
  701. }
  702. return safepostion
  703. }
  704.  
  705.  
  706. stock Get_Edit_Point_By_Aim(id)
  707. {
  708. new entList[1],team
  709. new Float:fOrigin[3],Float:vAngles[3],Float:vecReturn[3]
  710. entity_get_vector(id, EV_VEC_origin, fOrigin)
  711. fOrigin[2] += 10 // offset Z of id
  712. entity_get_vector(id, EV_VEC_v_angle, vAngles)
  713.  
  714. for(new Float:i=0.0;i<=1000.0;i+=20.0)
  715. {
  716. Vector_By_Angle(fOrigin,vAngles,i,1,vecReturn)
  717. //Make_TE_BEAMPOINTS(id,3,fOrigin,vecReturn,5,255)
  718. //client_print(0,print_chat,"fOrigin={%d,%d,%d},vecReturn={%d,%d,%d}",floatround(fOrigin[0]),floatround(fOrigin[1]),floatround(fOrigin[2]),floatround(vecReturn[0]),floatround(vecReturn[1]),floatround(vecReturn[2]))
  719.  
  720. find_sphere_class(0,EDIT_CLASSNAME, 20.0, entList, 1, vecReturn)
  721. if (entList[0]){
  722. // let entity have anim.
  723. entity_set_float(entList[0], EV_FL_animtime, 1.0)
  724. entity_set_float(entList[0], EV_FL_framerate, 1.0)
  725. team = entity_get_int(entList[0],EV_INT_iuser2)
  726. client_print(id,print_center,"%L #%d",id,"MSG_AIM_SPAWN",(team==1) ? "T":"CT",entList[0])
  727. if (task_exists(entList[0]+RESETENTITYTASKID))
  728. remove_task(entList[0]+RESETENTITYTASKID)
  729. set_task(CHECKTIMER+0.1,"reset_entity_stats",entList[0]+RESETENTITYTASKID)
  730. break
  731. }
  732. }
  733. return entList[0] // return entity if be found
  734. }
  735.  
  736.  
  737. /* FRU define in vector.inc
  738. #define ANGLEVECTOR_FORWARD 1
  739. #define ANGLEVECTOR_RIGHT 2
  740. #define ANGLEVECTOR_UP 3
  741. */
  742. stock Vector_By_Angle(Float:fOrigin[3],Float:vAngles[3], Float:multiplier, FRU, Float:vecReturn[3])
  743. {
  744. angle_vector(vAngles, FRU, vecReturn)
  745. vecReturn[0] = vecReturn[0] * multiplier + fOrigin[0]
  746. vecReturn[1] = vecReturn[1] * multiplier + fOrigin[1]
  747. vecReturn[2] = vecReturn[2] * multiplier + fOrigin[2]
  748. }
  749.  
  750.  
  751. // draw laserBeam
  752. stock Make_TE_BEAMPOINTS(id,color,Float:Vec1[3],Float:Vec2[3],width,brightness){
  753. message_begin(MSG_ONE_UNRELIABLE ,SVC_TEMPENTITY,{0,0,0},id)
  754. write_byte(TE_BEAMPOINTS) // TE_BEAMPOINTS = 0
  755. write_coord(floatround(Vec1[0])) // start position
  756. write_coord(floatround(Vec1[1]))
  757. write_coord(floatround(Vec1[2]))
  758. write_coord(floatround(Vec2[0])) // end position
  759. write_coord(floatround(Vec2[1]))
  760. write_coord(floatround(Vec2[2]))
  761. write_short(Laser_Spr) // sprite index
  762. write_byte(1) // starting frame
  763. write_byte(0) // frame rate in 0.1's
  764. write_byte(4) // life in 0.1's
  765. write_byte(width) // line width in 0.1's
  766. write_byte(0) // noise amplitude in 0.01's
  767. write_byte(g_BeamColors[color][0])
  768. write_byte(g_BeamColors[color][1])
  769. write_byte(g_BeamColors[color][2])
  770. write_byte(brightness) // brightness)
  771. write_byte(0) // scroll speed in 0.1's
  772. message_end()
  773. }
  774.  
  775.  
  776. stock Save_SpawnsFile()
  777. {
  778. if (file_exists(g_SpawnFile))
  779. delete_file(g_SpawnFile)
  780.  
  781. new mapname[32],line[128]
  782. get_mapname(mapname,31)
  783. format(line,127,"/* %s T=%d,CT=%d */ Map Spawns Editor Format File",mapname,g_EditT,g_EditCT)
  784. write_file(g_SpawnFile, line, -1)
  785.  
  786. new entity,team
  787. while ((entity = find_ent_by_class(entity, EDIT_CLASSNAME))){
  788. team = entity_get_int(entity,EV_INT_iuser2)
  789. Point_WriteToFlie(g_SpawnFile,team,entity,1)
  790. }
  791.  
  792. return 1
  793. }
  794.  
  795. stock Export_RipentFormatFile()
  796. {
  797. if (file_exists(g_EntFile))
  798. delete_file(g_EntFile)
  799.  
  800. new entity,team
  801. while ((entity = find_ent_by_class(entity, EDIT_CLASSNAME))){
  802. team = entity_get_int(entity,EV_INT_iuser2)
  803. Point_WriteToFlie(g_EntFile,team,entity,2)
  804. }
  805. return 1
  806. }
  807.  
  808. // store one entity data to file
  809. stock Point_WriteToFlie(Flie[],team,entity,saveformat)
  810. {
  811. new line[128],sTeam[32]
  812. new nOrigin[3],nAngles[3]
  813. new Float:fOrigin[3],Float:fAngles[3]
  814.  
  815. entity_get_vector(entity, EV_VEC_origin, fOrigin)
  816. entity_get_vector(entity, EV_VEC_angles, fAngles)
  817. FVecIVec(fOrigin,nOrigin)
  818. FVecIVec(fAngles,nAngles)
  819. if (nAngles[1]>=360) nAngles[1] -= 360
  820. if (nAngles[1]<0) nAngles[1] += 360
  821.  
  822. if (saveformat==1){ // write for plugin using format
  823. if (team==1) sTeam = "T"
  824. else sTeam = "CT"
  825. format(line, 127, "%s %d %d %d %d %d %d", sTeam, nOrigin[0], nOrigin[1], nOrigin[2], 0, nAngles[1], 0)
  826. write_file(Flie, line, -1)
  827. }
  828. else if (saveformat==2){ // write for ripent.exe format
  829. if (team==1) sTeam = "info_player_deathmatch"
  830. else sTeam = "info_player_start"
  831. format(line, 127,"{^n ^"classname^" ^"%s^"",sTeam)
  832. write_file(Flie, line , -1)
  833. format(line, 127, " ^"origin^" ^"%d %d %d^"", nOrigin[0], nOrigin[1], nOrigin[2])
  834. write_file(Flie, line, -1)
  835. format(line, 127, " ^"angle^" ^"0 %d 0^"^n}^n", nAngles[1])
  836. write_file(Flie, line, -1)
  837. }
  838. }
  839.  
  840. //////////////////////////////////////////////////////////
  841. /* export spawns data to txt file for ripent.exe format */
  842. /*
  843. { //(T)
  844. "classname" "info_player_deathmatch"
  845. "origin" "-384 1056 108"
  846. "angle" "0 180 0"
  847. }
  848. { //(CT)
  849. "classname" "info_player_start"
  850. "origin" "-128 -832 104"
  851. "angle" "0 270 0"
  852. }
  853. */
  854. //////////////////////////////////////////////////////////
  855.  
  856.