Jump to content

giulix

Registrado sin publicaciones
  • Contenido

    26
  • Ingreso

  • Última visita

Todo lo publicado por giulix

  1. no me gusto en ningun moemento me rei :S
  2. Forbidden You don't have permission to access /v2/cs16_c0/cs16full_by_clanco.exe on this server. Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request. Apache/1.3.33 Server at AppStuff Port 80
  3. Counter Strike BY 3LP1TUF0 Luego probe con ESTE , el Counter Strike 1.6 v49 Full Ninguno me funciona, el de la web directamente ni me inicia el juego me dice algo de que la configuracion de la pantalla esta mal y va a inciar el software mode pero no inicia :S
  4. ya van 4 veces que lo reinstale :S
  5. Buenas gente la cuestrion es asi, no puedo dirijirme al new game, para poner OK, les muestro una img en ese momento se me traba, no puedo apretar ninguna tecla tengo que dirijirme a administrador de tareas para poder finalizar el proceso, por si las dudas, lo prendo con la configuracion default, tengo W7, no lo puse con el Sxe. Saludos
  6. giuli.acdc | Giulix.-
  7. esto no se hace llamar una comunidad virtual publica en el cual una persona que se registra puede expresarse libremente ? think about it
  8. Claro, pero a lo que voy es que lo quiero activar en NEW GAME o en mi servidor dedicado, pero el AMX no anda :S
  9. giulix

    [Pedido] Wallpaper

    Propósito de la imágen: Abstracta, Tamaño: lo que mide un wallpaper Colores: Negro y Rojo Texto : Giulix.- Supernatural Detalles: un wallpaper como el estilo de swatto que ese la verdad que me encanto, pero de distintos colores, Muchas gracias Imagen de diseño opcional, por si el que me la quiere hacer se queda sin opciones
  10. Buenas gente bueno tengo un pequeño problema que quiero setear mi sv dedicado con ZP y bots, puse los ZBOTS que descargan los suelos automaticamente, asique son los mejores, con eso no hubo problema, el problema es cuando estoy en el game, ya sea NEW GAME O SV DEDICADO NO ME ANDA EL AMX :enojado: es frustrante , es decir, ya lo tengo seteado y es mas tengo el ZP 1.6 advanced, y no se me activa, probe con amx_on y nada asique nose que sera, si son tan amables me podrian ayudar, Los Quiero
  11. ALMORZANDO CON MIRTHA LEGRAND SANTO BIASATTI CULPABLES Culpables fue una serie de televisión emitida durante el año 2001 por la pantalla de El Trece y producida por Pol-ka. Esta serie fue la sucesora de Vulnerables y Verdad Consecuencia y antecesora de Locas de amor. Tuvo mucha repercusión en cuanto a público y crítica durante su emisión, alcanzando muy buenos niveles de audiencia y obteniendo numerosos premios, entre ellos el Martín Fierro de Oro. El guión estaba escrito por Juan José Campanella y Fernando Castets y la dirección a cargo de Daniel Barone. FÚTBOL DE PRIMERA ANTONIO GASALLA SUSANA GIMENEZ OFF: LALOLA MIRTHA LEGRAND MONTECRISTO MUJERES ASESINAS PADRE CORAJE RESISTIRE MAGDALENA RUIZ GUIÑAZU LOS SIMULADORES NACHO BARAHONA Nacho Barahona, montador de cine y televisión Español, acreditado con más de 225 capítulos de series de televisión, 14 cortometrajes, numerosos anuncios publicitarios, 3 documentales y 8 nominaciones. Nacido en (Madrid, 1970) OFF: TELENOCHE MARCELO TINELLI
  12. Descripcion: Si queres crear Niveles por AmmoPacks de una Forma Completa y Buena, entonces este Tutorial es para vos. Nota: Este Tutorial lo recopile de varias partes, no es completamente mio, ni siquiera hize un 5% del Code de este Tutorial Yo lo hacia de otra forma, pero esta me resultaron mejores. Nota2: Este Tutorial fue echo en el ZombiePlague 4.2 No se si anda en la 4.3 // Abajo de los Includes de tu ZombiePlague, pones: new const NIVELES[5] = { 0, 5, 10, 20, 50 } // Como veran, ahi estamos Creando una Constante con el Nombre "NIVELES" que abarcara (Para Explicarlo de una Manera que lo Entiendan), unos 5 Niveles. // Si van a poner mas Niveles, deberan cambiar ese "5" por la Cantidad de Niveles que vayan a poner. // Abajo de esa Constante creamos una Variable que contendra 33 Lugares. new g_level[33] // Nos dirigimos a la Forward: public fw_PlayerKilled(victim, attacker, shouldgib) { // Adentro de este Public, buscamos la siguiente linea: if (g_zombie[attacker] && (!g_nemesis[attacker] || !get_pcvar_num(cvar_nemignoreammo))) g_ammopacks[attacker] += get_pcvar_num(cvar_ammoinfect) // Y lo reemplazamos por esto: if (g_zombie[attacker] && (!g_nemesis[attacker] || !get_pcvar_num(cvar_nemignoreammo))) update_ap(attacker, get_pcvar_num(cvar_ammoinfect), 0) // La Funcion "update_ap" la llamaremos mas tarde. } // Ahora nos dirigimos a la Forward: public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type) { // Y adentro de este Public buscamos esta linea: g_ammopacks[attacker]++ // La reemplazamos por: update_ap(attacker, 1, 0) // El primer numero(1), que esta despues del Index(attacker), son los AmmoPacks que recibira el Index(attacker=atacante). // El otro numero no nos servira por ahora. // En este mismo Public buscamos esta linea que se encuentra mas abajo: g_ammopacks[attacker] += get_pcvar_num(cvar_ammoinfect) // ammo packs given to zombie for infection // La reemplazamos por: update_ap(attacker, get_pcvar_num(cvar_ammoinfect), 0) // ammo packs given to zombie for infection } // Buscamos el CLCMD: public clcmd_buyammo(id) { // Y adentro de este Public buscamos esta linea: g_ammopacks[id]-- // Y la reemplazamos por: update_ap(id, -1, 0) } // Ahora buscamos lo siguiente en el Plugin: buy_extra_item(id, itemid) { // Aca adentro buscamos una linea que diga lo siguiente: // Deduce item cost g_ammopacks[id] -= g_extraitem_cost[itemid] // La reemplazamos por: update_ap(id, 0 - g_extraitem_cost[itemid], 0) } // Ahora buscamos la Funcion: infection_explode(ent) { // Aca adentro buscamos la siguiente Linea: g_ammopacks[attacker] += get_pcvar_num(cvar_ammoinfect) // ammo packs given to zombie for infection // Y la reemplazamos por: update_ap(attacker, get_pcvar_num(cvar_ammoinfect), 0) // ammo packs given to zombie for infection } // Buscamos la Native: public native_set_user_ammo_packs(id, amount) { // Reemplazamos todo lo que esta aca adentro por: return update_ap(id, 0 - g_ammopacks[id] + amount, 0) } // Ahora nos vamos al FINAL DEL PLUGIN, incluso abajo de un: "#endif", y ponemos lo siguiente: // FORMA DE SPEED! [CON EL "goto"] // FORMA DE SPEED! [CON EL "goto"] // FORMA DE SPEED! [CON EL "goto"] public update_ap(id, amount, check) { if (check) goto check2 // Lo que hace el "goto" es, si la Funcion esta se llamo desde "check", el Plugin lo que hara, es llamar directamente a "check2". // Aca detectamos que si es Nivel Maximo no suba mas. if (g_ammopacks[id] + amount > NIVELES[sizeof NIVELES - 1] - 1) return PLUGIN_HANDLED // Le damos los APs correspondientes. g_ammopacks[id] += amount // Ya lo dijimos antes ^^. check2: if(amount < 0) { if(g_ammopacks[id] < NIVELES[g_level[id]] ) { g_level[id]-- client_print(id, print_center, "Bajaste de nivel") update_ap(id, -1, 1) } } else { if(g_ammopacks[id] >= NIVELES[g_level[id]] ) { g_level[id]++ client_print(id, print_center, "Subiste de nivel") update_ap(id, 0, 1) } } return PLUGIN_HANDLED } // FORMA DE CAPOSTRIKE93! [sIN EL "goto"] // FORMA DE CAPOSTRIKE93! [sIN EL "goto"] // FORMA DE CAPOSTRIKE93! [sIN EL "goto"] public update_ap(id, amount, check) { if (!check) { if (g_ammopacks[id] + amount > NIVELES[sizeof NIVELES - 1] - 1) return PLUGIN_HANDLED g_ammopacks[id] += amount } else { if(amount < 0) { if(g_ammopacks[id] < NIVELES[g_level[id]]) { g_level[id]-- client_print(id, print_center, "Bajaste de nivel") update_ap(id, -1, 1) } } else { if(g_ammopacks[id] >= NIVELES[g_level[id]]) { g_level[id]++ client_print(id, print_center, "Subiste de nivel") update_ap(id, 0, 1) } } } return PLUGIN_HANDLED } Listo esto fue todo para hacer Niveles. Creditos a Kiske por el verdadero Thread
  13. Cuando nos dan un archivo .sma o nos dan un codigo de un plugin. Que debemos hacer? Por ejemplo nos dan este codigo: #include #include new PLUGIN[]="Plugin de ejemplo" new AUTHOR[]="Giulix.-" new VERSION[]="0.1" public plugin_init(){ register_plugin(PLUGIN,VERSION,AUTHOR) register_cvar("nv_ejemplo","0") } Lo que debemos hacer es lo siguiente: 1- Copiar el codigo en un archivo de texto. 2- Guardarlo como formato sma (quedaria ejemplo.sma). 3- Llevar el archivo a la carpeta addons/amxmodx/scripting. 4- Abrir Compile.exe. Cuando termine presionar una tecla. 5- Si el archivo se compilo bien, estara dentro de compiled. Y una manera mas sencilla es usando un compilador web como ESTE. Solo que a veces el compilador web no esta actualizado para la version del AMXX. El unico requisito de este tutorial es tener la ultima version de AMXX, ya que probablemente con otras versiones anteriores hay cosas que no estan.
  14. Esta es la lista ORDENADA de los puntos a leer en este tutorial, favor de seguir el orden correspondiente para su correcto entendimiento: Comentarios : ayuda a las personas a que entiendan tu codigo (o tambien te ayuda a vos) Variables : como guardar datos Arrays y Strings : como guardar datos multiples, palabras y frases Funciones : creando nuestras funciones Natives : usando funciones ya creadas Forwards : obtener informacion o realizar cierta accion cuando algo ocurre Estructura : ejemplo de estructura de un plugin Algunos Tips : unos pequeños tips que te serviran a la hora de empezar Otras Ayudas : una lista de guias y tutoriales que te van a servir para seguir aprendiendo Nota: Tengan en cuenta que lo mostrado en este thread son solo ejemplos, algunos posiblemente no funcionen si los copian y pegan, esto es principalmente para aprender de que forma se hacen ciertas cosas dentro del AMXX Scripting. Primero, podriamos asociar a un plugin como si fuera una bodega. En la bodega encontramos cajas (se podrian considerar VARIABLES), tambien maquinas (se podrian considerar funciones), carga y recibo de mercaderia (forwards y returns), y puertas que nos conectan hacia otras bodegas (natives). * Claro que deben hacer de cuenta que esto se parece a una bodega /guiño Comentarios Una de las primeras cosas que debes saber sobre el codeo de plugins (aunque se podria decir sobre la programacion en general), es el uso de COMENTARIOS. Los comentarios sirven para agregar diferentes notaciones al codigo del plugin, lo cual ayuda a que los demas puedan entender diferentes cosas de TU codigo o aclarar algunas partes, o incluso para hacer un tutorial mostrando codigo. Aunque no solamente sirve para ayudar a otros, tambien puede que te sirva tener tus propias anotaciones para uso personal. Los comentarios pueden ir en cualquier parte del codigo, no tienen un lugar obligatorio. Cabe aclarar tambien, que solo sirve para la lectura del codigo, no para otra cosa... el compilador no lee ni compila ningun comentario. Ejemplo: Un comentario equivalente expresado en codigo seria asi: // PELIGRO: Michael Jackson paso por aca, no deje a sus hijos sueltos Y obviamente podemos agregarle mas informacion y mas comentarios: / / PELIGRO: Michael Jackson paso por aca, no deje a sus hijos sueltos // Pero despues del 25 de Junio de 2009, ya no nos tenemos que preocupar mas por eso Otro uso de comentarios es que uno puede agregar ciertas anotaciones para luego no olvidarse de agregar algo al codigo, o algo similar. Tambien se usan mucho los comentarios para agregar informacion del plugin (descripcion, cvars, comandos, historial de versiones, etc), pero esto se detallara mas adelante. Cada lenguaje de programacion tiene diferentes tipos de comentarios, o diferentes formas de realizarlo, en PAWN tenemos 2 tipos: Comentario de una sola linea Comentario de multiples lineas El Comentario de una sola linea comienza con // y todo lo siguiente a // es ignorado por el compilador. Puede ser usado al principio de una linea o en el medio: // Esto es correcto codigo aqui // esto tambien es correcto El Comentario de multiples lineas comienza con /* y termina con */. Todo lo que se encuentra dentro de estos 2 es ignorado, por lo tanto se puede comentar varias lineas de una forma mas practica que el otro tipo de comentario. /* Este tipo de comentario tambien puede ser usado en una sola linea */ /* O tambien puede ser usado en multiples lineas, en este caso se le da un mejor uso */ /* Y tambien puede ser usado de esta forma */ Variables Ahora entrando mas en lo que es el codigo (que si va a ser compilado). Nos encontramos con una de las cosas principales y mas usadas, las variables. Que seguramente las hayan visto en matematica, cuando hablamos de X, de como X puede representar un numero. En el codigo, una variable puede ser representado como si fuera una caja: Una caja en la que le podemos asignar un valor, o mejor dicho guardar un valor dentro de esa caja (pero esto se mostrara despues). Para crear una variable, debemos hacerlo de la siguiente manera: new nombre_de_variable Podemos utilizar el nombre que querramos, aunque siempre es conveniente usar un nombre que representa lo que vamos a guardar adentro de esa variable. Recuerden tambien que el nombre de la variable no puede comenzar con un numero, pero si puede contenerlos en el nombre, tampoco puede llevar ningun caracter raro, excepto el guion bajo "_". Y tampoco puede llevar espacios, para eso se usa el guion bajo mayormente. Como dijimos, el nombre de la variable tiene que ser acorde a lo que vamos a guardar dentro de ella, por lo tanto en este ejemplo vamos a usar esta variable para guardar la cantidad de manzanas que tenemos: El nombre de la variable, no tiene que ser obligatoriamente la representacion del uso que le vamos a dar, pero si es recomendable hacerlo para que se entienda el codigo, para que nosotros nos entendamos y tambien que nos puedan entender. Es ilogico ponerle el nombre a una variable como "manzanas" cuando en realidad vamos a guardar la cantidad de alfajores que tenemos, por ejemplo. Tengan en cuenta que al crear una nueva variable, si al momento de crearla no le asignamos ningun valor, por defecto esa variable va a contener el valor 0. Y luego podemos cambiar el valor de esa variable al numero que nosotros queramos, de la siguiente forma: nombre_de_variable = 3 Entonces lo que hacemos es cambiar el numero inicial 0 al 3 y el resultado seria este: Tambien deben saber que pueden crear la variable y asignarle un numero al momento de crearla, por lo que en ningun momenot esa variable contendra el valor de 0. Un ejemplo: new manzanas = 5 Sepan tambien que el signo igual (=) es usado para asignar (o cambiar) valores. En cambio el signo igual igual (==) es usado para comparar (o chequear) valores. Una variable siempre va a ser usada para contener un numero, y a su vez se puede ir modificando dependiendo el uso que le demos y tambien podemos usar operadores matematicos. Como por ejemplo: new manzanas = 5 + 3 Entonces la variable manzanas va a contener el valor 8. Tambien, dependiendo el uso que le den y las distintas variables que usen dentro de su codigo, pueden hacer algo como esto: new manzanas_mias = 5 new manzanas_de_pepe = 7 new resultado = manzanas_mias + manzanas_de_pepe // 5 + 7 Entonces luego de eso la variable resultado va el valor de la suma entre las otras dos variables, lo que va a dar un valor de 12. Espero que les halla servido, CREDITOS A ALUCARD DE ALLIED MODDERS
  15. ta ahi en el ducto, lo mate JAJA
  16. Family Guy The Simpsons Marito Baracus Cualcerdo YAPA Doblaje de Benny Benasy-Satisfaction Video original Video Doblado
  17. Aprendizaje necesario: Básico sobre algunas Funciones. Aprendizaje extra: Aprenderse el Include del FVault que está posteado en este Post. Bueno, no hay nada mas que decir, esta todo explicado en el Codigo. Sin ZombiePlague #include < amxmodx > #include < fakemeta > #include < fvault > #include < cstrike > // Creamos variables globales new SZ_Password[ 192 ] new SZ_Password_T[ 33 ][ 192 ] new Registrado[ 33 ] new BadPassword[ 33 ] new const Vault[] = "_Datos" // Nombre del Archivo donde se guardaran los Datos. public plugin_init( ) { register_plugin( "Tutorial", "1.0", "Kiske" ) register_forward( FM_ClientUserInfoChanged, "FWClientUserInfoChanged" ) // Si no me equivoco esta forward se llama cuando el usuario cambia algo de su setinfo. register_clcmd( "say /registrarse", "CMDRegistrarse" ) register_clcmd( "IntroducirContrasenia", "CMDIntroducirContrasenia" ) } public client_disconnect( Index ) Save( Index ) // Esta función ponganla en todos los lugares donde quieren que se guarden sus cosas. public client_putinserver( Index ) { Registrado[ Index ] = 0 BadPassword[ Index ] = 0 Load( Index ) } public CMDRegistrarse( Index ) { if( Registrado[ Index ] || BadPassword[ Index ] ) return PLUGIN_HANDLED; client_cmd( Index, "messagemode IntroducirContrasenia" ) return PLUGIN_CONTINUE; } public CMDIntroducirContrasenia( Index ) { read_args( SZ_Password, 191 ) // Ponemos en la Variable SZ_Password lo que escribió como Contraseña remove_quotes( SZ_Password ) // Analiza lo que escribimos trim( SZ_Password ) // Esta opción es para remover los ESPACIOS ( si es que puso ) al principio y al final de lo que escribió if( equal( SZ_Password, "" ) || contain( SZ_Password, " ") != -1) // En la primer parte, verificamos si lo que ingresó contiene algo......y en la segunda parte verificamos si lo que ingresó tiene espacios, si coincide alguna de las dos cosas, no se lo aceptamos. return PLUGIN_HANDLED; else // Si se llama esta parte, quiere decir que lo que ingresó contiene algo y no tiene espacios. { client_cmd( Index, "setinfo _pass ^"%s^"", SZ_Password ) // Creamos una Setinfo al jugador con el prefijo _pass y la contraseña que ingresó. Ustedes si quieren cambienle el prefijo. Registrado[ Index ] = 1 // Guardamos el Nombre, ls Password y el Dinero actual static SZ_Name[ 32 ], SZ_Data[ 512 ] get_user_name( Index, SZ_Name, 31 ) // Si quieren agregar mas Datos solo vayan aumentando el Parametro y las Variables. formatex( SZ_Data, charsmax( SZ_Data ), "%s %d", SZ_Password, cs_get_user_money( Index ) ) // Esta función del FVault sirve para setear datos ( Recomiendo: Que lean el Include del FVault que está posteado al final de este Post ) fvault_set_data( Vault, SZ_Name, SZ_Data ) // Fixeamos un Error ya que si es la Primera vez que se registra, cuando llame al Save no aparecerá ninguna Password, esto lo Fixea. SZ_Password_T[ Index ] = SZ_Password return PLUGIN_HANDLED; } return PLUGIN_CONTINUE; } public Save( Index ) { if( !Registrado[ Index ] || BadPassword[ Index ] ) // Si NO esta registrado, o si tiene la Contraseña Incorrecta, no le guardamos nada. return PLUGIN_HANDLED; // Voy a dar un Ejemplo en el caso de que quieran guardar Dinero o lo que sea. static SZ_Data[ 512 ], SZ_Name[ 32 ] formatex( SZ_Data, charsmax( SZ_Data ), "%s %d", SZ_Password_T[ Index ], cs_get_user_money( Index ) ) get_user_name( Index, SZ_Name, 31 ) fvault_set_data( Vault, SZ_Name, SZ_Data ) return PLUGIN_CONTINUE; } public Load( Index ) { static SZ_Data[ 512 ], SZ_Name[ 32 ], SETINFO_Password[ 191 ], VAULT_Password[ 191 ], Dinero[ 11 ] get_user_name( Index, SZ_Name, 31 ) get_user_info( Index, "_pass", SETINFO_Password, 190 ) // Seteamos en SETINFO_Password lo que tiene como Setinfo con el prefijo _pass if( !fvault_get_data( Vault, SZ_Name, SZ_Data, charsmax( SZ_Data ) ) ) // Detectamos si NO existe su Nombre y Data en el Vault. En ese caso, les dejo a su Creatividad para que piensen. return 0; Registrado[ Index ] = 1 // El Nombre y la Password JAMÁS la cargen. // Voy a dar un Ejemplo en el caso de que quieran cargar Dinero o lo que sea. parse( SZ_Data, VAULT_Password, 190, Dinero, 10 ) // La función PARSE, separa los Datos 1 por 1. Si guardamos la Password primero, y el Dinero despues, entonces este Parse está bien, obviamente tiene que seguir el Orden en el que se guardó. if( equal( SETINFO_Password, VAULT_Password ) ) // Si la Contraseña del Jugador coincide con la Registrada de su Nick, cargamos sus Datos. { // Fixeamos un Error para que no reemplaze la Password Registrada por alguna que puede llegar a cambiar el adentro del Server. SZ_Password_T[ Index ] = SETINFO_Password // Cargamos el Dinero. ( Numero ) cs_set_user_money( Index, str_to_num( Dinero ) ) // Si cargan una Variable es así: // Money = str_to_num( Dinero ) // Y si cargan una Native como en el caso de cs_set_user_money, bueno ya esta puesto arriba. // Ejemplo de: Cargar un Float // Variable_De_Float[ Index ] = str_to_float( Float ) return 2; } else // Si la Contraseña del Jugador NO coincide con la Registrada de su Nick, podemos Kickearlo, mandarlo a Spect, un menú, les dejo su creatividad... { BadPassword[ Index ] = 1 //.... } return 1; } public FWClientUserInfoChanged( Index, Buffer ) { if( !is_user_connected( Index ) ) return FMRES_IGNORED; static NickName[32], NickOld[32]; get_user_name( Index, NickOld, 31 ) engfunc( EngFunc_InfoKeyValue, Buffer, "name", NickName, 31 ) // Si tampoco me confundo, esto obtiene el valor "name" de su setinfo. if( equal( NickName, NickOld ) ) return FMRES_IGNORED; engfunc( EngFunc_SetClientKeyValue, Index, Buffer, "name", NickOld ) // Le volvemos a poner el nick viejo para que no se lo pueda cambiar. client_cmd( Index, "name ^"%s^"; setinfo name ^"%s^"", NickOld, NickOld ) return FMRES_SUPERCEDE; } Datos Extras: Una vez que te Registraste, no te podes volver a Registrar CON el mismo NICK. Si tenes la Password incorrecta, les dejo a su creatividad lo que quieran hacer, ahi ya dice donde es que le da la Password incorrecta, obviamente no te podes volver a Registrar. Cuando se te guardan los Datos por primera vez es algo asi: "Giulix" "cachoenlacolina 800" Cuando me desconecte, que se guardan los Datos, se me guardaron así: "Giulix" "cachoenlacolina 4600", obviamente porque gane Dinero. Testee todos los Bugs posibles, y 0 errores. Con ZombiePlague y con Menú de Registro y Logeo #include < fvault > // Creamos variables globales new SZ_Password[ 33 ][ 192 ] new SZ_Password_T[ 33 ][ 192 ] new Registrado[ 33 ] new BadPassword[ 33 ] new const Vault[] = "_Datos" // Nombre del Archivo donde se guardaran los Datos. public plugin_init( ) { register_clcmd( "say /registrarse", "CMDRegistrarse" ) register_clcmd( "IntroducirContrasenia", "CMDIntroducirContrasenia" ) } public client_disconnect( Index ) Save( Index ) // Esta función ponganla en todos los lugares donde quieren que se guarden sus cosas. public client_putinserver( Index ) { Registrado[ Index ] = 0 BadPassword[ Index ] = 0 set_task( 0.1, "clcmd_changeteam", Index ) // Les va a aparecer el Menú igual por más que tengan MOTD y esas mierdas. // Esta función ponganla abajo del reset_vars y abajo del statssave. Load( Index ) } // ATENCIÓN ACA !!: // En la Función que se llama: clcmd_changeteam(id) van a reemplazar todo lo que tengan por esto, a continuacion les explico: public clcmd_changeteam( Index ) { static Team; Team = get_user_team( Index ) if( ( Team == 0 || Team == 3 ) && !BadPassword[ Index ] && Registrado[ Index ] ) // Si esta en el Team UNNASIGNED o SPECTATOR, si tiene bien la Password y si está Registrado... return PLUGIN_CONTINUE; // ... le muestra el Menú de Teams. else if( !Registrado[ Index ] || BadPassword[ Index ] ) // Si no está Registrado o tiene mal la Password, le mostramos el Menú de Registro y Login. { static Menu, SZ_Items[ 32 ] Menu = menu_create( "\yTitulo", "MenuBadPassword" ) formatex( SZ_Items, 31, "%s", !Registrado[ Index ] ? "Registrar nueva Cuenta" : "Ingresar Contraseña" ) menu_additem( Menu, SZ_Items, "1" ) //* Si no está Registrado la Opción esta será: "Registrar nueva Cuenta", de lo contrario será: "Ingresar Contraseña". menu_setprop( Menu, MPROP_EXITNAME, "Salir" ) menu_display( Index, Menu, 0 ) return PLUGIN_HANDLED; } else show_menu_game( Index ) // Si le cambiaron el nombre a esta función, también deben cambiarselo acá. return PLUGIN_HANDLED; } public CMDRegistrarse( Index ) { if( Registrado[ Index ] || BadPassword[ Index ] ) return PLUGIN_HANDLED; client_cmd( Index, "messagemode IntroducirContrasenia" ) return PLUGIN_CONTINUE; } public CMDIntroducirContrasenia( Index ) { read_args( SZ_Password[ Index ], charsmax( SZ_Password[ ] ) ) // Ponemos en la Variable SZ_Password lo que escribió como Contraseña remove_quotes( SZ_Password[ Index ] ) // Analiza lo que escribimos trim( SZ_Password[ Index ] ) // Esta opción es para remover los ESPACIOS ( si es que puso ) al principio y al final de lo que escribió if( equal( SZ_Password[ Index ], "" ) || contain( SZ_Password[ Index ], " ") != -1) // En la primer parte, verificamos si lo que ingresó contiene algo......y en la segunda parte verificamos si lo que ingresó tiene espacios, si coincide alguna de las dos cosas, no se lo aceptamos. return PLUGIN_HANDLED; else if( BadPassword[ Index ] ) // Si se llama esta parte, quiere decir que lo que ingresó contiene algo y no tiene espacios, pero también quiere decir que está Introduciendo la Contraseña para Logearse. { static SZ_Data[ 512 ], SZ_Name[ 32 ], VAULT_Password[ 191 ] get_user_name( Index, SZ_Name, 31 ) if( !fvault_get_data( Vault, SZ_Name, SZ_Data, charsmax( SZ_Data ) ) ) return 0; parse( SZ_Data, VAULT_Password, 190 ) if( equal( SZ_Password[ Index ], VAULT_Password ) ) // Si lo que Ingreso coincide con la Password Registrada, lo mandamos a la Selección de Teams. { client_cmd( Index, "setinfo _pass ^"%s^"", SZ_Password[ Index ] ) BadPassword[ Index ] = 0 Load( Index ) // Fixeamos un Error ya que si es la Primera vez que se registra, cuando llame al Save no aparecerá ninguna Password, esto lo Fixea. SZ_Password_T[ Index ] = SZ_Password[ Index ] return PLUGIN_HANDLED; } return PLUGIN_HANDLED; } else // Si se llama esta parte, quiere decir que lo que ingresó contiene algo y no tiene espacios. { client_cmd( Index, "setinfo _pass ^"%s^"", SZ_Password[ Index ] ) // Creamos una Setinfo al jugador con el prefijo _pass y la contraseña que ingresó. Ustedes si quieren cambienle el prefijo. Registrado[ Index ] = 1 // Guardamos el Nombre, ls Password y los AmmoPacks actuales static SZ_Name[ 32 ], SZ_Data[ 512 ] get_user_name( Index, SZ_Name, 31 ) // Si quieren agregar mas Datos solo vayan aumentando los parametros con su respectiva variable. formatex( SZ_Data, charsmax( SZ_Data ), "%s %d", SZ_Password[ Index ], g_ammopacks[index] ) // Esta función del FVault sirve para setear datos ( Recomiendo: Que lean el Include del FVault que está posteado al final de este Post ) fvault_set_data( Vault, SZ_Name, SZ_Data ) // Fixeamos un Error ya que si es la Primera vez que se registra, cuando llame al Save no aparecerá ninguna Password, esto lo Fixea. SZ_Password_T[ Index ] = SZ_Password[ Index ] return PLUGIN_HANDLED; } return PLUGIN_CONTINUE; } public Save( Index ) { if( !Registrado[ Index ] || BadPassword[ Index ] ) // Si NO esta registrado, o si tiene la Contraseña Incorrecta, no le guardamos nada. return PLUGIN_HANDLED; static SZ_Data[ 512 ], SZ_Name[ 32 ] // Guardamos la Data. formatex( SZ_Data, charsmax( SZ_Data ), "%s %d", SZ_Password_T[ Index ], g_ammopacks[index] ) get_user_name( Index, SZ_Name, 31 ) fvault_set_data( Vault, SZ_Name, SZ_Data ) return PLUGIN_CONTINUE; } Load( Index ) { static SZ_Data[ 512 ], SZ_Name[ 32 ], SETINFO_Password[ 191 ], VAULT_Password[ 191 ], APs[ 11 ] get_user_name( Index, SZ_Name, 31 ) get_user_info( Index, "_pass", SETINFO_Password, 190 ) // Seteamos en SETINFO_Password lo que tiene como Setinfo con el prefijo _pass if( !fvault_get_data( Vault, SZ_Name, SZ_Data, charsmax( SZ_Data ) ) ) // Detectamos si NO existe su Nombre y Data en el Vault. En ese caso, yo puse que lo mande al Menu de Teams ( Donde le pusimos que se Registre ). { set_task( 0.1, "clcmd_changeteam", Index ) // Si le cambiaron el nombre a esta función, también deben cambiarselo acá. Si no les aparece el Menú de Teams cuando hacen esto, usen set_task de 0.2 return 0; } Registrado[ Index ] = 1 // El Nombre y la Password JAMÁS la cargen. parse( SZ_Data, VAULT_Password, 190, APs, 10 ) // La función PARSE, separa los Datos 1 por 1. Si guardamos la Password primero, y los AmmoPacks despues, entonces este Parse está bien, obviamente tiene que seguir el Orden en el que se guardó. if( equal( SETINFO_Password, VAULT_Password ) ) // Si la Contraseña del Jugador coincide con la Registrada de su Nick, cargamos sus Datos. { // Fixeamos un Error para que no reemplaze la Password Registrada por alguna que puede llegar a cambiar el adentro del Server. SZ_Password_T[ Index ] = SETINFO_Password // Cargamos los AmmoPacks. ( Numero ) g_ammopacks[index] = str_to_num( APs ) set_task( 0.1, "clcmd_changeteam", Index ) // Si le cambiaron el nombre a esta función, también deben cambiarselo acá. Si no les aparece el Menú de Teams cuando hacen esto, usen set_task de 0.2 // Ejemplo de: Cargar un Float // Variable_De_Float[index] = str_to_float( Float ) return 2; } else // Si la Contraseña del Jugador NO coincide con la Registrada de su Nick, podemos Kickearlo, mandarlo a Spect, un menú, etc.. { BadPassword[ Index ] = 1 // Yo le voy a poner que si tiene mal la Password lo mande a Spect y el Menú de Ingresar la Password. set_task( 0.1, "clcmd_changeteam", Index ) // Si le cambiaron el nombre a esta función, también deben cambiarselo acá. Si no les aparece el Menú de Teams cuando hacen esto, usen set_task de 0.2. //.... } return 1; } public MenuBadPassword( Index, Menu, Item ) { if( Item == MENU_EXIT ) { menu_destroy( Menu ) return PLUGIN_HANDLED; } static Access, Data[6], iName[64], CallBack menu_item_getinfo( Menu, Item, Access, Data, 5, iName, 63, CallBack ) switch( str_to_num( Data ) ) { case 1: { if( !Registrado[ Index ] ) CMDRegistrarse( Index ) else client_cmd( Index, "messagemode IntroducirContrasenia" ) } } menu_destroy( Menu ) return PLUGIN_HANDLED; } Datos Extras: Una vez que te Registraste, no te podes volver a Registrar CON el mismo NICK. Si tenes la Password incorrecta, los manda a un Menú de Logeo. Cuando se te guardan los Datos por primera vez es algo asi: "Giulix" "cachoenlacolina 800" Cuando me desconecte, que se guardan los Datos, se me guardaron así: "Giulix" "cachoenlacolina 4600", obviamente porque gane AmmoPacks. No testee nada asi que si encuentran algún POSIBLE Bug, me lo hacen saber. Algo que también quiero aclarar, es que para prohibir el CAMBIO de NICK, se fijen la primera parte SIN ZombiePlague, y fijense la Forward: register_forward( FM_ClientUserInfoChanged, "FWClientUserInfoChanged" ) que les va a servir para que no causen Bugs con los Nicks. Bugs Encontrados: Cuando te aparece el Menu de Registro / Login, si entras a otro Menú, se bugea y te deja entrar de CT y / o TT. SOLUCIÓN: La única que logré hacer yo y efectiva, es bloqueando que entre a otros Menúes si Registrado[ Index ] era igual a 0 y / o si BadPassword[ Index ] era igual a 1. ¿ Como bloquear un Menú para que no pueda acceder a el si esas Variables están mal. ? Todos los Menúes accesibles por SAY y / o CONSOLA, van a hacer que se bugeen, la solución es poner donde se llama la Función que se crea el MENÚ, el siguiente código: if( !Registrado[ Index ] || BadPassword[ Index] ) return; Este pequeño cógido, deben ponerlo en todos los Menúes que se pueda acceder a traves de SAY y / o CONSOLA Creditos a Kiske de allied modders
  18. Nose donde esta el error ese es el problema
  19. new const PLUGIN_VERSION[] = "1.1 $Revision: 290 $"; // $Date: 2009-02-26 11:20:25 -0500 (Thu, 26 Feb 2009) $; #include #include #pragma semicolon 1 #define TASKID_EMPTYSERVER 98176977 #define TASKID_REMINDER 52691153 #define RTV_CMD_STANDARD 1 #define RTV_CMD_SHORTHAND 2 #define RTV_CMD_DYNAMIC 4 #define SOUND_GETREADYTOCHOOSE 1 #define SOUND_COUNTDOWN 2 #define SOUND_TIMETOCHOOSE 4 #define SOUND_RUNOFFREQUIRED 8 #define MAPFILETYPE_SINGLE 1 #define MAPFILETYPE_GROUPS 2 #define SHOWSTATUS_VOTE 1 #define SHOWSTATUS_END 2 #define SHOWSTATUSTYPE_COUNT 1 #define SHOWSTATUSTYPE_PERCENTAGE 2 #define ANNOUNCECHOICE_PLAYERS 1 #define ANNOUNCECHOICE_ADMINS 2 #define MAX_NOMINATION_CNT 5 #define MAX_PREFIX_CNT 32 #define MAX_RECENT_MAP_CNT 16 #define MAX_PLAYER_CNT 32 #define MAX_STANDARD_MAP_CNT 25 #define MAX_MAPNAME_LEN 31 #define MAX_MAPS_IN_VOTE 8 #define MAX_NOM_MATCH_CNT 1000 #define VOTE_IN_PROGRESS 1 #define VOTE_FORCED 2 #define VOTE_IS_RUNOFF 4 #define VOTE_IS_OVER 8 #define VOTE_IS_EARLY 16 #define VOTE_HAS_EXPIRED 32 #define SRV_START_CURRENTMAP 1 #define SRV_START_NEXTMAP 2 #define SRV_START_MAPVOTE 3 #define SRV_START_RANDOMMAP 4 #define LISTMAPS_USERID 0 #define LISTMAPS_LAST 1 #define TIMELIMIT_NOT_SET -1.0 new MENU_CHOOSEMAP[] = "gal_menuChooseMap"; new DIR_CONFIGS[64]; new DIR_DATA[64]; new CLR_RED[3]; // \r new CLR_WHITE[3]; // \w new CLR_YELLOW[3]; // \y new CLR_GREY[3]; // \d new bool:g_wasLastRound = false; new g_mapPrefix[MAX_PREFIX_CNT][16], g_mapPrefixCnt = 1; new g_currentMap[MAX_MAPNAME_LEN+1], Float:g_originalTimelimit = TIMELIMIT_NOT_SET; new g_nomination[MAX_PLAYER_CNT + 1][MAX_NOMINATION_CNT + 1], g_nominationCnt, g_nominationMatchesMenu[MAX_PLAYER_CNT]; //new g_nonOverlapHudSync; new g_voteWeightFlags[32]; new Array:g_emptyCycleMap, bool:g_isUsingEmptyCycle = false, g_emptyMapCnt = 0; new Array:g_mapCycle; new g_recentMap[MAX_RECENT_MAP_CNT][MAX_MAPNAME_LEN + 1], g_cntRecentMap; new Array:g_nominationMap, g_nominationMapCnt; new Array:g_fillerMap; new Float:g_rtvWait; new bool:g_rockedVote[MAX_PLAYER_CNT + 1], g_rockedVoteCnt; new g_mapChoice[MAX_MAPS_IN_VOTE + 1][MAX_MAPNAME_LEN + 1], g_choiceCnt, g_choiceMax; new bool:g_voted[MAX_PLAYER_CNT + 1] = {true, ...}, g_mapVote[MAX_MAPS_IN_VOTE + 1]; new g_voteStatus, g_voteDuration, g_votesCast; new g_runoffChoice[2]; new g_vote[512]; new bool:g_handleMapChange = true; new g_refreshVoteStatus = true, g_voteTallyType[3], g_snuffDisplay[MAX_PLAYER_CNT + 1]; new g_menuChooseMap; new g_pauseMapEndVoteTask, g_pauseMapEndManagerTask; new cvar_extendmapMax, cvar_extendmapStep; new cvar_endOnRound, cvar_endOfMapVote; new cvar_rtvWait, cvar_rtvRatio, cvar_rtvCommands; new cvar_cmdVotemap, cvar_cmdListmaps, cvar_listmapsPaginate; new cvar_banRecent, cvar_banRecentStyle, cvar_voteDuration; new cvar_nomMapFile, cvar_nomPrefixes; new cvar_nomQtyUsed, cvar_nomPlayerAllowance; new cvar_voteExpCountdown, cvar_voteWeightFlags, cvar_voteWeight; new cvar_voteMapChoiceCnt, cvar_voteAnnounceChoice, cvar_voteUniquePrefixes; new cvar_voteMapFile, cvar_rtvReminder; new cvar_srvStart; new cvar_emptyWait, cvar_emptyMapFile, cvar_emptyCycle; new cvar_runoffEnabled, cvar_runoffDuration; new cvar_voteStatus, cvar_voteStatusType; new cvar_soundsMute; public plugin_init() { // build version information new jnk[1], version[8], rev[8]; parse(PLUGIN_VERSION, version, sizeof(version)-1, jnk, sizeof(jnk)-1, rev, sizeof(rev)-1, jnk, sizeof(jnk)-1); new pluginVersion[16]; formatex(pluginVersion, sizeof(pluginVersion)-1, "%s.%s", version, rev); register_plugin("Galileo", pluginVersion, "Brad Jones"); register_cvar("gal_version", pluginVersion, FCVAR_SERVER|FCVAR_SPONLY); set_cvar_string("gal_version", pluginVersion); register_cvar("gal_server_starting", "1", FCVAR_SPONLY); cvar_emptyCycle = register_cvar("gal_in_empty_cycle", "0", FCVAR_SPONLY); register_cvar("gal_debug", "0"); register_dictionary("common.txt"); register_dictionary("nextmap.txt"); register_dictionary("galileo.txt"); if (module_exists("cstrike")) { register_event("HLTV", "event_round_start", "a", "1=0", "2=0"); } else if (module_exists("dodx")) { register_event("RoundState", "event_round_start", "a", "1=1"); } register_event("TextMsg", "event_game_commencing", "a", "2=#Game_Commencing", "2=#Game_will_restart_in"); register_event("30", "event_intermission", "a"); g_menuChooseMap = register_menuid(MENU_CHOOSEMAP); register_menucmd(g_menuChooseMap, MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5|MENU_KEY_6|MENU_KEY_7|MENU_KEY_8|MENU_KEY_9|MENU_KEY_0, "vote_handleChoice"); register_clcmd("say", "cmd_say", -1); register_clcmd("say nextmap", "cmd_nextmap", 0, "- displays nextmap"); register_clcmd("say currentmap", "cmd_currentmap", 0, "- display current map"); register_clcmd("say ff", "cmd_ff", 0, "- display friendly fire status"); // grrface register_clcmd("votemap", "cmd_HL1_votemap"); register_clcmd("listmaps", "cmd_HL1_listmaps"); register_concmd("gal_startvote", "cmd_startVote", ADMIN_MAP); register_concmd("gal_createmapfile", "cmd_createMapFile", ADMIN_RCON); register_cvar("amx_nextmap", "", FCVAR_SERVER|FCVAR_EXTDLL|FCVAR_SPONLY); cvar_extendmapMax = register_cvar("amx_extendmap_max", "90"); cvar_extendmapStep = register_cvar("amx_extendmap_step", "15"); cvar_cmdVotemap = register_cvar("gal_cmd_votemap", "0"); cvar_cmdListmaps = register_cvar("gal_cmd_listmaps", "2"); cvar_listmapsPaginate = register_cvar("gal_listmaps_paginate", "10"); cvar_banRecent = register_cvar("gal_banrecent", "3"); cvar_banRecentStyle = register_cvar("gal_banrecentstyle", "1"); cvar_endOnRound = register_cvar("gal_endonround", "1"); cvar_endOfMapVote = register_cvar("gal_endofmapvote", "1"); cvar_emptyWait = register_cvar("gal_emptyserver_wait", "0"); cvar_emptyMapFile = register_cvar("gal_emptyserver_mapfile", ""); cvar_srvStart = register_cvar("gal_srv_start", "0"); cvar_rtvCommands = register_cvar("gal_rtv_commands", "3"); cvar_rtvWait = register_cvar("gal_rtv_wait", "10"); cvar_rtvRatio = register_cvar("gal_rtv_ratio", "0.60"); cvar_rtvReminder = register_cvar("gal_rtv_reminder", "2"); cvar_nomPlayerAllowance = register_cvar("gal_nom_playerallowance", "2"); cvar_nomMapFile = register_cvar("gal_nom_mapfile", "mapcycle"); cvar_nomPrefixes = register_cvar("gal_nom_prefixes", "1"); cvar_nomQtyUsed = register_cvar("gal_nom_qtyused", "0"); cvar_voteWeight = register_cvar("gal_vote_weight", "2"); cvar_voteWeightFlags = register_cvar("gal_vote_weightflags", "y"); cvar_voteMapFile = register_cvar("gal_vote_mapfile", "mapcycle.txt"); cvar_voteDuration = register_cvar("gal_vote_duration", "15"); cvar_voteExpCountdown = register_cvar("gal_vote_expirationcountdown", "1"); cvar_voteMapChoiceCnt = register_cvar("gal_vote_mapchoices", "5"); cvar_voteAnnounceChoice = register_cvar("gal_vote_announcechoice", "1"); cvar_voteStatus = register_cvar("gal_vote_showstatus", "1"); cvar_voteStatusType = register_cvar("gal_vote_showstatustype", "2"); cvar_voteUniquePrefixes = register_cvar("gal_vote_uniqueprefixes", "0"); cvar_runoffEnabled = register_cvar("gal_runoff_enabled", "0"); cvar_runoffDuration = register_cvar("gal_runoff_duration", "10"); cvar_soundsMute = register_cvar("gal_sounds_mute", "0"); //set_task(1.0, "dbg_test",_,_,_,"a", 15); } public dbg_fakeVotes() { if (!(g_voteStatus & VOTE_IS_RUNOFF)) { g_mapVote[0] += 2; // map 1 g_mapVote[1] += 0; // map 2 g_mapVote[2] += 6; // map 3 g_mapVote[3] += 0; // map 4 g_mapVote[4] += 0; // map 5 g_mapVote[5] += 4; // extend option g_votesCast = g_mapVote[0] + g_mapVote[1] + g_mapVote[2] + g_mapVote[3] + g_mapVote[4] + g_mapVote[5]; } else if (g_voteStatus & VOTE_IS_RUNOFF) { g_mapVote[0] += 1; // choice 1 g_mapVote[1] += 0; // choice 2 g_votesCast = g_mapVote[0] + g_mapVote[1]; } } public plugin_cfg() { formatex(DIR_CONFIGS[get_configsdir(DIR_CONFIGS, sizeof(DIR_CONFIGS)-1)], sizeof(DIR_CONFIGS)-1, "/galileo"); formatex(DIR_DATA[get_datadir(DIR_DATA, sizeof(DIR_DATA)-1)], sizeof(DIR_DATA)-1, "/galileo"); server_cmd("exec %s/galileo.cfg", DIR_CONFIGS); server_exec(); if (colored_menus()) { copy(CLR_RED, 2, "\r"); copy(CLR_WHITE, 2, "\w"); copy(CLR_YELLOW, 2, "\y"); } g_rtvWait = get_pcvar_float(cvar_rtvWait); get_pcvar_string(cvar_voteWeightFlags, g_voteWeightFlags, sizeof(g_voteWeightFlags)-1); get_mapname(g_currentMap, sizeof(g_currentMap)-1); g_choiceMax = max(min(MAX_MAPS_IN_VOTE, get_pcvar_num(cvar_voteMapChoiceCnt)), 2); // g_nonOverlapHudSync = CreateHudSyncObj(); g_fillerMap = ArrayCreate(32); g_nominationMap = ArrayCreate(32); // initialize nominations table nomination_clearAll(); if (get_pcvar_num(cvar_banRecent)) { register_clcmd("say recentmaps", "cmd_listrecent", 0); map_loadRecentList(); if (!(get_cvar_num("gal_server_starting") && get_pcvar_num(cvar_srvStart))) { map_writeRecentList(); } } if (get_pcvar_num(cvar_rtvCommands) & RTV_CMD_STANDARD) { register_clcmd("say rockthevote", "cmd_rockthevote", 0); } if (get_pcvar_num(cvar_nomPlayerAllowance)) { register_concmd("gal_listmaps", "cmd_listmaps"); register_clcmd("say nominations", "cmd_nominations", 0, "- displays current nominations for next map"); if (get_pcvar_num(cvar_nomPrefixes)) { map_loadPrefixList(); } map_loadNominationList(); } new mapName[32]; get_mapname(mapName, 31); dbg_log(6, "[%s]", mapName); dbg_log(6, ""); if (get_cvar_num("gal_server_starting")) { srv_handleStart(); } set_task(10.0, "vote_setupEnd"); if (get_pcvar_num(cvar_emptyWait)) { g_emptyCycleMap = ArrayCreate(32); map_loadEmptyCycleList(); set_task(60.0, "srv_initEmptyCheck"); } } public plugin_end() { map_restoreOriginalTimeLimit(); } public vote_setupEnd() { dbg_log(4, "%32s mp_timelimit: %f g_originalTimelimit: %f", "vote_setupEnd(in)", get_cvar_float("mp_timelimit"), g_originalTimelimit); g_originalTimelimit = get_cvar_float("mp_timelimit"); new nextMap[32]; if (get_pcvar_num(cvar_endOfMapVote)) { formatex(nextMap, sizeof(nextMap)-1, "%L", LANG_SERVER, "GAL_NEXTMAP_UNKNOWN"); } else { g_mapCycle = ArrayCreate(32); map_populateList(g_mapCycle, "mapcycle.txt"); map_getNext(g_mapCycle, g_currentMap, nextMap); } map_setNext(nextMap); // as long as the time limit isn't set to 0, we can manage the end of the map automatically if (g_originalTimelimit) { set_task(15.0, "vote_manageEnd", _, _, _, "b"); } dbg_log(2, "%32s mp_timelimit: %f g_originalTimelimit: %f", "vote_setupEnd(out)", get_cvar_float("mp_timelimit"), g_originalTimelimit); } map_getNext(Array:mapArray, currentMap[], nextMap[32]) { new thisMap[32], mapCnt = ArraySize(mapArray), nextmapIdx = 0, returnVal = -1; for (new mapIdx = 0; mapIdx < mapCnt; mapIdx++) { ArrayGetString(mapArray, mapIdx, thisMap, sizeof(thisMap)-1); if (equal(currentMap, thisMap)) { nextmapIdx = (mapIdx == mapCnt - 1) ? 0 : mapIdx + 1; returnVal = nextmapIdx; break; } } ArrayGetString(mapArray, nextmapIdx, nextMap, sizeof(nextMap)-1); return returnVal; } public srv_handleStart() { // this is the key that tells us if this server has been restarted or not set_cvar_num("gal_server_starting", 0); // take the defined "server start" action new startAction = get_pcvar_num(cvar_srvStart); if (startAction) { new nextMap[32]; if (startAction == SRV_START_CURRENTMAP || startAction == SRV_START_NEXTMAP) { new filename[256]; formatex(filename, sizeof(filename)-1, "%s/info.dat", DIR_DATA); new file = fopen(filename, "rt"); if (file) // !feof(file) { fgets(file, nextMap, sizeof(nextMap)-1); if (startAction == SRV_START_NEXTMAP) { nextMap[0] = 0; fgets(file, nextMap, sizeof(nextMap)-1); } } fclose(file); } else if (startAction == SRV_START_RANDOMMAP) { // pick a random map from allowable nominations // if noms aren't allowed, the nomination list hasn't already been loaded if (get_pcvar_num(cvar_nomPlayerAllowance) == 0) { map_loadNominationList(); } if (g_nominationMapCnt) { ArrayGetString(g_nominationMap, random_num(0, g_nominationMapCnt - 1), nextMap, sizeof(nextMap)-1); } } trim(nextMap); if (nextMap[0] && is_map_valid(nextMap)) { server_cmd("changelevel %s", nextMap); } else { vote_manageEarlyStart(); } } } vote_manageEarlyStart() { g_voteStatus |= VOTE_IS_EARLY; set_task(120.0, "vote_startDirector"); } map_setNext(nextMap[]) { // set the queryable cvar set_cvar_string("amx_nextmap", nextMap); // update our data file new filename[256]; formatex(filename, sizeof(filename)-1, "%s/info.dat", DIR_DATA); new file = fopen(filename, "wt"); if (file) { fprintf(file, "%s", g_currentMap); fprintf(file, "^n%s", nextMap); fclose(file); } else { //error } } public vote_manageEnd() { new secondsLeft = get_timeleft(); // are we ready to start an "end of map" vote? if (secondsLeft < 150 && secondsLeft > 90 && !g_pauseMapEndVoteTask && get_pcvar_num(cvar_endOfMapVote) && !get_pcvar_num(cvar_emptyCycle)) { vote_startDirector(false); } // are we managing the end of the map? if (secondsLeft < 20 && !g_pauseMapEndManagerTask) { map_manageEnd(); } } public map_loadRecentList() { new filename[256]; formatex(filename, sizeof(filename)-1, "%s/recentmaps.dat", DIR_DATA); new file = fopen(filename, "rt"); if (file) { new buffer[32]; while (!feof(file)) { fgets(file, buffer, sizeof(buffer)-1); trim(buffer); if (buffer[0]) { if (g_cntRecentMap == get_pcvar_num(cvar_banRecent)) { break; } copy(g_recentMap[g_cntRecentMap++], sizeof(buffer)-1, buffer); } } fclose(file); } } public map_writeRecentList() { new filename[256]; formatex(filename, sizeof(filename)-1, "%s/recentmaps.dat", DIR_DATA); new file = fopen(filename, "wt"); if (file) { fprintf(file, "%s", g_currentMap); for (new idxMap = 0; idxMap < get_pcvar_num(cvar_banRecent) - 1; ++idxMap) { fprintf(file, "^n%s", g_recentMap[idxMap]); } fclose(file); } } public map_loadFillerList(filename[]) { return map_populateList(g_fillerMap, filename); } public cmd_rockthevote(id) { client_print(id, print_chat, "%L", id, "GAL_CMD_RTV"); vote_rock(id); return PLUGIN_CONTINUE; } public cmd_nominations(id) { client_print(id, print_chat, "%L", id, "GAL_CMD_NOMS"); nomination_list(id); return PLUGIN_CONTINUE; } public cmd_nextmap(id) { new map[32]; get_cvar_string("amx_nextmap", map, sizeof(map)-1); client_print(0, print_chat, "%L %s", LANG_PLAYER, "NEXT_MAP", map); return PLUGIN_CONTINUE; } public cmd_currentmap(id) { client_print(0, print_chat, "%L: %s", LANG_PLAYER, "PLAYED_MAP", g_currentMap); return PLUGIN_CONTINUE; } public cmd_listrecent(id) { switch (get_pcvar_num(cvar_banRecentStyle)) { case 1: { new msg[101], msgIdx; for (new idx = 0; idx < g_cntRecentMap; ++idx) { msgIdx += format(msg[msgIdx], sizeof(msg)-1-msgIdx, ", %s", g_recentMap[idx]); } client_print(0, print_chat, "%L: %s", LANG_PLAYER, "GAL_MAP_RECENTMAPS", msg[2]); } case 2: { for (new idx = 0; idx < g_cntRecentMap; ++idx) { client_print(0, print_chat, "%L (%i): %s", LANG_PLAYER, "GAL_MAP_RECENTMAP", idx+1, g_recentMap[idx]); } } } return PLUGIN_HANDLED; } public cmd_startVote(id, level, cid) { if (!cmd_access(id, level, cid, 1)) return PLUGIN_HANDLED; if (g_voteStatus & VOTE_IN_PROGRESS) { client_print(id, print_chat, "%L", id, "GAL_VOTE_INPROGRESS"); } else if (g_voteStatus & VOTE_IS_OVER) { client_print(id, print_chat, "%L", id, "GAL_VOTE_ENDED"); } else { // we may not want to actually change the map after outcome of vote is determined if (read_argc() == 2) { new arg[32]; read_args(arg, sizeof(arg)-1); if (equali(arg, "-nochange")) { g_handleMapChange = false; } } vote_startDirector(true); } return PLUGIN_HANDLED; } map_populateList(Array:mapArray, mapFilename[]) { // clear the map array in case we're reusing it ArrayClear(mapArray); // load the array with maps new mapCnt; if (!equal(mapFilename, "*")) { new file = fopen(mapFilename, "rt"); if (file) { new buffer[32]; while (!feof(file)) { fgets(file, buffer, sizeof(buffer)-1); trim(buffer); if (buffer[0] && !equal(buffer, "//", 2) && !equal(buffer, ";", 1) && is_map_valid(buffer)) { ArrayPushString(mapArray, buffer); ++mapCnt; } } fclose(file); } else { log_error(AMX_ERR_NOTFOUND, "%L", LANG_SERVER, "GAL_MAPS_FILEMISSING", mapFilename); } } else { // no file provided, assuming contents of "maps" folder new dir, mapName[32]; dir = open_dir("maps", mapName, sizeof(mapName)-1); if (dir) { new lenMapName; while (next_file(dir, mapName, sizeof(mapName)-1)) { lenMapName = strlen(mapName); if (lenMapName > 4 && equali(mapName[lenMapName - 4], ".bsp", 4)) { mapName[lenMapName-4] = '^0'; if (is_map_valid(mapName)) { ArrayPushString(mapArray, mapName); ++mapCnt; } } } close_dir(dir); } else { // directory not found, wtf? log_error(AMX_ERR_NOTFOUND, "%L", LANG_SERVER, "GAL_MAPS_FOLDERMISSING"); } } return mapCnt; } public map_loadNominationList() { new filename[256]; get_pcvar_string(cvar_nomMapFile, filename, sizeof(filename)-1); g_nominationMapCnt = map_populateList(g_nominationMap, filename); } // grrface, this has no place in a map choosing plugin. just replicating it because it's in AMXX's public cmd_ff() { client_print(0, print_chat, "%L: %L", LANG_PLAYER, "FRIEND_FIRE", LANG_PLAYER, get_cvar_num("mp_friendlyfire") ? "ON" : "OFF"); return PLUGIN_CONTINUE; } public cmd_createMapFile(id, level, cid) { if (!cmd_access(id, level, cid, 1)) return PLUGIN_HANDLED; new cntArg = read_argc() - 1; switch (cntArg) { case 1: { new arg1[256]; read_argv(1, arg1, sizeof(arg1)-1); remove_quotes(arg1); new mapName[MAX_MAPNAME_LEN+5]; // map name is 31 (i.e. MAX_MAPNAME_LEN), ".bsp" is 4, string terminator is 1. new dir, file, mapCnt, lenMapName; dir = open_dir("maps", mapName, sizeof(mapName)-1); if (dir) { new filename[256]; formatex(filename, sizeof(filename)-1, "%s/%s", DIR_CONFIGS, arg1); file = fopen(filename, "wt"); if (file) { mapCnt = 0; while (next_file(dir, mapName, sizeof(mapName)-1)) { lenMapName = strlen(mapName); if (lenMapName > 4 && equali(mapName[lenMapName - 4], ".bsp", 4)) { mapName[lenMapName- 4] = '^0'; if (is_map_valid(mapName)) { mapCnt++; fprintf(file, "%s^n", mapName); } } } fclose(file); con_print(id, "%L", LANG_SERVER, "GAL_CREATIONSUCCESS", filename, mapCnt); } else { con_print(id, "%L", LANG_SERVER, "GAL_CREATIONFAILED", filename); } close_dir(dir); } else { // directory not found, wtf? con_print(id, "%L", LANG_SERVER, "GAL_MAPSFOLDERMISSING"); } } default: { // inform of correct usage con_print(id, "%L", id, "GAL_CMD_CREATEFILE_USAGE1"); con_print(id, "%L", id, "GAL_CMD_CREATEFILE_USAGE2"); } } return PLUGIN_HANDLED; } public map_loadPrefixList() { new filename[256]; formatex(filename, sizeof(filename)-1, "%s/prefixes.ini", DIR_CONFIGS); new file = fopen(filename, "rt"); if (file) { new buffer[16]; while (!feof(file)) { fgets(file, buffer, sizeof(buffer)-1); if (buffer[0] && !equal(buffer, "//", 2)) { if (g_mapPrefixCnt <= MAX_PREFIX_CNT) { trim(buffer); copy(g_mapPrefix[g_mapPrefixCnt++], sizeof(buffer)-1, buffer); } else { log_error(AMX_ERR_BOUNDS, "%L", LANG_SERVER, "GAL_PREFIXES_TOOMANY", MAX_PREFIX_CNT, filename); break; } } } fclose(file); } else { log_error(AMX_ERR_NOTFOUND, "%L", LANG_SERVER, "GAL_PREFIXES_NOTFOUND", filename); } return PLUGIN_HANDLED; } map_loadEmptyCycleList() { new filename[256]; get_pcvar_string(cvar_emptyMapFile, filename, sizeof(filename)-1); g_emptyMapCnt = map_populateList(g_emptyCycleMap, filename); } public map_manageEnd() { dbg_log(2, "%32s mp_timelimit: %f", "map_manageEnd(in)", get_cvar_float("mp_timelimit")); g_pauseMapEndManagerTask = true; if (get_realplayersnum() <= 1) { // at most there is only one player on the server, so no need to stay around map_change(); } else { if (get_pcvar_num(cvar_endOnRound) && g_wasLastRound == false) { // let the server know it's the last round g_wasLastRound = true; // let the players know it's the last round if (g_voteStatus & VOTE_FORCED) { client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_CHANGE_NEXTROUND"); } else { client_print(0, print_chat, "%L %L", LANG_PLAYER, "GAL_CHANGE_TIMEEXPIRED", LANG_PLAYER, "GAL_CHANGE_NEXTROUND"); } // prevent the map from ending automatically server_cmd("mp_timelimit 0"); } else { // freeze the game and show the scoreboard message_begin(MSG_ALL, SVC_INTERMISSION); message_end(); //new chatTime = floatround(get_cvar_float("mp_chattime"), floatround_floor); // display intermission expiration countdown //set_task(1.0, "intermission_displayTimer", chatTime, _, _, "a", chatTime); // change the map after "chattime" is over set_task(floatmax(get_cvar_float("mp_chattime"), 2.0), "map_change"); } new map[MAX_MAPNAME_LEN + 1]; get_cvar_string("amx_nextmap", map, sizeof(map)-1); client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_NEXTMAP", map); } dbg_log(2, "%32s mp_timelimit: %f", "map_manageEnd(out)", get_cvar_float("mp_timelimit")); } /* public intermission_displayTimer(originalChatTime) { static secondsLeft = -1; if (secondsLeft == -1) { secondsLeft = originalChatTime; } secondsLeft--; client_print(0, print_center, "Intermission ends in %i seconds.", secondsLeft); client_print(0, print_chat, "%i seconds", secondsLeft); set_hudmessage(255, 0, 90, 0.80, 0.20, 0, 1.0, 2.0, 0.1, 0.1, -1); // set_hudmessage(0, 222, 50, -1.0, 0.13, 0, 1.0, 0.94, 0.0, 0.0, -1); show_hudmessage(0, "Intermission ends in %i seconds.", secondsLeft); // use audio since visual doesn't seem to work // something like "map will change in 2 seconds" } */ public event_round_start() { if (g_wasLastRound) { map_manageEnd(); } } public event_game_commencing() { // make sure the reset time is the original time limit // (can be skewed if map was previously extended) map_restoreOriginalTimeLimit(); } public event_intermission() { // don't let the normal end interfere g_pauseMapEndManagerTask = true; // change the map after "chattime" is over set_task(floatmax(get_cvar_float("mp_chattime"), 2.0), "map_change"); return PLUGIN_CONTINUE; } map_getIdx(text[]) { new map[MAX_MAPNAME_LEN + 1]; new mapIdx; new nominationMap[32]; for (new prefixIdx = 0; prefixIdx < g_mapPrefixCnt; ++prefixIdx) { formatex(map, sizeof(map)-1, "%s%s", g_mapPrefix[prefixIdx], text); for (mapIdx = 0; mapIdx < g_nominationMapCnt; ++mapIdx) { ArrayGetString(g_nominationMap, mapIdx, nominationMap, sizeof(nominationMap)-1); if (equal(map, nominationMap)) { return mapIdx; } } } return -1; } public cmd_say(id) { //----- // generic say handler to determine if we need to act on what was said //----- static text[70], arg1[32], arg2[32], arg3[2]; read_args(text, sizeof(text)-1); remove_quotes(text); arg1[0] = '^0'; arg2[0] = '^0'; arg3[0] = '^0'; parse(text, arg1, sizeof(arg1)-1, arg2, sizeof(arg2)-1, arg3, sizeof(arg3)-1); // if the chat line has more than 2 words, we're not interested at all if (arg3[0] == 0) { new idxMap; // if the chat line contains 1 word, it could be a map or a one-word command if (arg2[0] == 0) // "say [rtv|rockthevote]" { if ((get_pcvar_num(cvar_rtvCommands) & RTV_CMD_SHORTHAND && equali(arg1, "rtv")) || ((get_pcvar_num(cvar_rtvCommands) & RTV_CMD_DYNAMIC && equali(arg1, "rockthe", 7) && equali(arg1[strlen(arg1)-4], "vote")))) { vote_rock(id); return PLUGIN_HANDLED; } else if (get_pcvar_num(cvar_nomPlayerAllowance)) { if (equali(arg1, "noms")) { nomination_list(id); return PLUGIN_HANDLED; } else { idxMap = map_getIdx(arg1); if (idxMap >= 0) { nomination_toggle(id, idxMap); return PLUGIN_HANDLED; } } } } else if (get_pcvar_num(cvar_nomPlayerAllowance)) // "say " { if (equali(arg1, "nominate") || equali(arg1, "nom")) { nomination_attempt(id, arg2); return PLUGIN_HANDLED; } else if (equali(arg1, "cancel")) { // bpj -- allow ambiguous cancel in which case a menu of their nominations is shown idxMap = map_getIdx(arg2); if (idxMap >= 0) { nomination_cancel(id, idxMap); return PLUGIN_HANDLED; } } } } return PLUGIN_CONTINUE; } nomination_attempt(id, nomination[]) // (playerName[], &phraseIdx, matchingSegment[]) { // all map names are stored as lowercase, so normalize the nomination strtolower(nomination); // assume there'll be more than one match (because we're lazy) and starting building the match menu //menu_destroy(g_nominationMatchesMenu[id]); g_nominationMatchesMenu[id] = menu_create("Nominate Map", "nomination_handleMatchChoice"); // gather all maps that match the nomination new mapIdx, nominationMap[32], matchCnt = 0, matchIdx = -1, info[1], choice[64], disabledReason[16]; for (mapIdx = 0; mapIdx < g_nominationMapCnt && matchCnt <= MAX_NOM_MATCH_CNT; ++mapIdx) { ArrayGetString(g_nominationMap, mapIdx, nominationMap, sizeof(nominationMap)-1); if (contain(nominationMap, nomination) > -1) { matchCnt++; matchIdx = mapIdx; // store in case this is the only match // there may be a much better way of doing this, but I didn't feel like // storing the matches and mapIdx's only to loop through them again info[0] = mapIdx; // in most cases, the map will be available for selection, so assume that's the case here disabledReason[0] = 0; // disable if the map has already been nominated if (nomination_getPlayer(mapIdx)) { formatex(disabledReason, sizeof(disabledReason)-1, "%L", id, "GAL_MATCH_NOMINATED"); } // disable if the map is too recent else if (map_isTooRecent(nominationMap)) { formatex(disabledReason, sizeof(disabledReason)-1, "%L", id, "GAL_MATCH_TOORECENT"); } else if (equal(g_currentMap, nominationMap)) { formatex(disabledReason, sizeof(disabledReason)-1, "%L", id, "GAL_MATCH_CURRENTMAP"); } formatex(choice, sizeof(choice)-1, "%s %s", nominationMap, disabledReason); menu_additem(g_nominationMatchesMenu[id], choice, info, (disabledReason[0] == 0) ? 0 : (1<<26)); } } // handle the number of matches switch (matchCnt) { case 0: { // no matches; pity the poor fool client_print(id, print_chat, "%L", id, "GAL_NOM_FAIL_NOMATCHES", nomination); } case 1: { // one match?! omg, this is just like awesome map_nominate(id, matchIdx); } default: { // this is kinda sexy; we put up a menu of the matches for them to pick the right one client_print(id, print_chat, "%L", id, "GAL_NOM_MATCHES", nomination); if (matchCnt == MAX_NOM_MATCH_CNT) { client_print(id, print_chat, "%L", id, "GAL_NOM_MATCHES_MAX", MAX_NOM_MATCH_CNT, MAX_NOM_MATCH_CNT); } menu_display(id, g_nominationMatchesMenu[id]); } } } public nomination_handleMatchChoice(id, menu, item) { if( item < 0 ) return PLUGIN_CONTINUE; // Get item info new mapIdx, info[1]; new access, callback; menu_item_getinfo(g_nominationMatchesMenu[id], item, access, info, 1, _, _, callback); mapIdx = info[0]; map_nominate(id, mapIdx); return PLUGIN_HANDLED; } nomination_getPlayer(idxMap) { // check if the map has already been nominated new idxNomination; new playerNominationMax = min(get_pcvar_num(cvar_nomPlayerAllowance), MAX_NOMINATION_CNT); for (new idPlayer = 1; idPlayer <= MAX_PLAYER_CNT; ++idPlayer) { for (idxNomination = 1; idxNomination <= playerNominationMax; ++idxNomination) { if (idxMap == g_nomination[idPlayer][idxNomination]) { return idPlayer; } } } return 0; } nomination_toggle(id, idxMap) { new idNominator = nomination_getPlayer(idxMap); if (idNominator == id) { nomination_cancel(id, idxMap); } else { map_nominate(id, idxMap, idNominator); } } nomination_cancel(id, idxMap) { // cancellations can only be made if a vote isn't already in progress if (g_voteStatus & VOTE_IN_PROGRESS) { client_print(id, print_chat, "%L", id, "GAL_CANCEL_FAIL_INPROGRESS"); return; } // and if the outcome of the vote hasn't already been determined else if (g_voteStatus & VOTE_IS_OVER) { client_print(id, print_chat, "%L", id, "GAL_CANCEL_FAIL_VOTEOVER"); return; } new bool:nominationFound, idxNomination; new playerNominationMax = min(get_pcvar_num(cvar_nomPlayerAllowance), MAX_NOMINATION_CNT); for (idxNomination = 1; idxNomination <= playerNominationMax; ++idxNomination) { if (g_nomination[id][idxNomination] == idxMap) { nominationFound = true; break; } } new mapName[32]; ArrayGetString(g_nominationMap, idxMap, mapName, sizeof(mapName)-1); if (nominationFound) { g_nomination[id][idxNomination] = -1; g_nominationCnt--; nomination_announceCancellation(mapName); } else { new idNominator = nomination_getPlayer(idxMap); if (idNominator) { new name[32]; get_user_name(idNominator, name, 31); client_print(id, print_chat, "%L", id, "GAL_CANCEL_FAIL_SOMEONEELSE", mapName, name); } else { client_print(id, print_chat, "%L", id, "GAL_CANCEL_FAIL_WASNOTYOU", mapName); } } } map_nominate(id, idxMap, idNominator = -1) { // nominations can only be made if a vote isn't already in progress if (g_voteStatus & VOTE_IN_PROGRESS) { client_print(id, print_chat, "%L", id, "GAL_NOM_FAIL_INPROGRESS"); return; } // and if the outcome of the vote hasn't already been determined else if (g_voteStatus & VOTE_IS_OVER) { client_print(id, print_chat, "%L", id, "GAL_NOM_FAIL_VOTEOVER"); return; } new mapName[32]; ArrayGetString(g_nominationMap, idxMap, mapName, sizeof(mapName)-1); // players can not nominate the current map if (equal(g_currentMap, mapName)) { client_print(id, print_chat, "%L", id, "GAL_NOM_FAIL_CURRENTMAP", g_currentMap); return; } // players may not be able to nominate recently played maps if (map_isTooRecent(mapName)) { client_print(id, print_chat, "%L", id, "GAL_NOM_FAIL_TOORECENT", mapName); client_print(id, print_chat, "%L", id, "GAL_NOM_FAIL_TOORECENT_HLP"); return; } // check if the map has already been nominated if (idNominator == -1) { idNominator = nomination_getPlayer(idxMap); } if (idNominator == 0) { // determine the number of nominations the player already made // and grab an open slot with the presumption that the player can make the nomination new nominationCnt = 0, idxNominationOpen, idxNomination; new playerNominationMax = min(get_pcvar_num(cvar_nomPlayerAllowance), MAX_NOMINATION_CNT); for (idxNomination = 1; idxNomination <= playerNominationMax; ++idxNomination) { if (g_nomination[id][idxNomination] >= 0) { nominationCnt++; } else { idxNominationOpen = idxNomination; } } if (nominationCnt == playerNominationMax) { new nominatedMaps[256], buffer[32]; for (idxNomination = 1; idxNomination <= playerNominationMax; ++idxNomination) { idxMap = g_nomination[id][idxNomination]; ArrayGetString(g_nominationMap, idxMap, buffer, sizeof(buffer)-1); format(nominatedMaps, sizeof(nominatedMaps)-1, "%s%s%s", nominatedMaps, (idxNomination == 1) ? "" : ", ", buffer); } client_print(id, print_chat, "%L", id, "GAL_NOM_FAIL_TOOMANY", playerNominationMax, nominatedMaps); client_print(id, print_chat, "%L", id, "GAL_NOM_FAIL_TOOMANY_HLP"); } else { // otherwise, allow the nomination g_nomination[id][idxNominationOpen] = idxMap; g_nominationCnt++; map_announceNomination(id, mapName); client_print(id, print_chat, "%L", id, "GAL_NOM_GOOD_HLP"); } } else if (idNominator == id) { client_print(id, print_chat, "%L", id, "GAL_NOM_FAIL_ALREADY", mapName); } else { new name[32]; get_user_name(idNominator, name, 31); client_print(id, print_chat, "%L", id, "GAL_NOM_FAIL_SOMEONEELSE", mapName, name); client_print(id, print_chat, "%L", id, "GAL_NOM_FAIL_SOMEONEELSE_HLP"); } } public nomination_list(id) { new idxNomination, idxMap; //, hudMessage[512]; new msg[101], mapCnt; new playerNominationMax = min(get_pcvar_num(cvar_nomPlayerAllowance), MAX_NOMINATION_CNT); new mapName[32]; for (new idPlayer = 1; idPlayer <= MAX_PLAYER_CNT; ++idPlayer) { for (idxNomination = 1; idxNomination <= playerNominationMax; ++idxNomination) { idxMap = g_nomination[idPlayer][idxNomination]; if (idxMap >= 0) { ArrayGetString(g_nominationMap, idxMap, mapName, sizeof(mapName)-1); format(msg, sizeof(msg)-1, "%s, %s", msg, mapName); if (++mapCnt == 4) // list 4 maps per chat line { client_print(0, print_chat, "%L: %s", LANG_PLAYER, "GAL_NOMINATIONS", msg[2]); mapCnt = 0; msg[0] = 0; } // construct the HUD message // format(hudMessage, sizeof(hudMessage)-1, "%s^n%s", hudMessage, mapName); // construct the console message } } } if (msg[0]) { client_print(0, print_chat, "%L: %s", LANG_PLAYER, "GAL_NOMINATIONS", msg[2]); } else { client_print(0, print_chat, "%L: %L", LANG_PLAYER, "GAL_NOMINATIONS", LANG_PLAYER, "NONE"); } // set_hudmessage(255, 0, 90, 0.80, 0.20, 0, 1.0, 12.0, 0.1, 0.1, -1); // ShowSyncHudMsg(id, g_nonOverlapHudSync, hudMessage); } public vote_startDirector(bool:forced) { new choicesLoaded, voteDuration; if (g_voteStatus & VOTE_IS_RUNOFF) { choicesLoaded = vote_loadRunoffChoices(); voteDuration = get_pcvar_num(cvar_runoffDuration); if (get_realplayersnum()) { dbg_log(4, " [RUNOFF VOTE CHOICES (%i)]", choicesLoaded); } } else { // make it known that a vote is in progress g_voteStatus |= VOTE_IN_PROGRESS; // stop RTV reminders remove_task(TASKID_REMINDER); // set nextmap to "voting" if (forced || get_pcvar_num(cvar_endOfMapVote)) { new nextMap[32]; formatex(nextMap, sizeof(nextMap)-1, "%L", LANG_SERVER, "GAL_NEXTMAP_VOTING"); map_setNext(nextMap); } // pause the "end of map" tasks so they don't interfere g_pauseMapEndVoteTask = true; g_pauseMapEndManagerTask = true; if (forced) { g_voteStatus |= VOTE_FORCED; } choicesLoaded = vote_loadChoices(); voteDuration = get_pcvar_num(cvar_voteDuration); if (get_realplayersnum()) { dbg_log(4, " [PRIMARY VOTE CHOICES (%i)]", choicesLoaded); } if (choicesLoaded) { // clear all nominations nomination_clearAll(); } } if (choicesLoaded) { // alphabetize the maps SortCustom2D(g_mapChoice, choicesLoaded, "sort_stringsi"); // dbg code ---- if (get_realplayersnum()) { for (new dbgChoice = 0; dbgChoice < choicesLoaded; dbgChoice++) { dbg_log(4, " %i. %s", dbgChoice+1, g_mapChoice[dbgChoice]); } } //-------------- // mark the players who are in this vote for use later new player[32], playerCnt; get_players(player, playerCnt, "ch"); // skip bots and hltv for (new idxPlayer = 0; idxPlayer < playerCnt; ++idxPlayer) { g_voted[player[idxPlayer]] = false; } // make perfunctory announcement: "get ready to choose a map" if (!(get_pcvar_num(cvar_soundsMute) & SOUND_GETREADYTOCHOOSE)) { client_cmd(0, "spk ^"get red(e80) ninety(s45) to check(e20) use bay(s18) mass(e42) cap(s50)^""); } // announce the pending vote countdown from 7 to 1 set_task(1.0, "vote_countdownPendingVote", _, _, _, "a", 7); // display the map choices set_task(8.5, "vote_handleDisplay"); // display the vote outcome if (get_pcvar_num(cvar_voteStatus)) { new arg[3] = {-1, -1, false}; // indicates it's the end of vote display set_task(8.5 + float(voteDuration) + 1.0, "vote_display", _, arg, 3); set_task(8.5 + float(voteDuration) + 6.0, "vote_expire"); } else { set_task(8.5 + float(voteDuration) + 3.0, "vote_expire"); } } else { client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_VOTE_NOMAPS"); } if (get_realplayersnum()) { dbg_log(4, ""); dbg_log(4, " [PLAYER CHOICES]"); } } public vote_countdownPendingVote() { static countdown = 7; // visual countdown set_hudmessage(0, 222, 50, -1.0, 0.13, 0, 1.0, 0.94, 0.0, 0.0, -1); show_hudmessage(0, "%L", LANG_PLAYER, "GAL_VOTE_COUNTDOWN", countdown); // audio countdown if (!(get_pcvar_num(cvar_soundsMute) & SOUND_COUNTDOWN)) { new word[6]; num_to_word(countdown, word, 5); client_cmd(0, "spk ^"fvox/%s^"", word); } // decrement the countdown countdown--; if (countdown == 0) { countdown = 7; } } vote_addNominations() { // dbg code ---- if (get_realplayersnum()) { dbg_log(4, " [NOMINATIONS (%i)]", g_nominationCnt); } //-------------- if (g_nominationCnt) { // set how many total nominations we can use in this vote new maxNominations = get_pcvar_num(cvar_nomQtyUsed); new slotsAvailable = g_choiceMax - g_choiceCnt; new voteNominationMax = (maxNominations) ? min(maxNominations, slotsAvailable) : slotsAvailable; // set how many total nominations each player is allowed new playerNominationMax = min(get_pcvar_num(cvar_nomPlayerAllowance), MAX_NOMINATION_CNT); // add as many nominations as we can // [TODO: develop a better method of determining which nominations make the cut; either FIFO or random] new idxMap, id, mapName[32]; // dbg code ---- if (get_realplayersnum()) { new nominator_id, playerName[32]; for (new idxNomination = playerNominationMax; idxNomination >= 1; --idxNomination) { for (id = 1; id <= MAX_PLAYER_CNT; ++id) { idxMap = g_nomination[id][idxNomination]; if (idxMap >= 0) { ArrayGetString(g_nominationMap, idxMap, mapName, sizeof(mapName)-1); nominator_id = nomination_getPlayer(idxMap); get_user_name(nominator_id, playerName, sizeof(playerName)-1); dbg_log(4, " %-32s %s", mapName, playerName); } } } dbg_log(4, ""); } //-------------- for (new idxNomination = playerNominationMax; idxNomination >= 1; --idxNomination) { for (id = 1; id <= MAX_PLAYER_CNT; ++id) { idxMap = g_nomination[id][idxNomination]; if (idxMap >= 0) { ArrayGetString(g_nominationMap, idxMap, mapName, sizeof(mapName)-1); copy(g_mapChoice[g_choiceCnt++], sizeof(g_mapChoice[])-1, mapName); if (g_choiceCnt == voteNominationMax) { break; } } } if (g_choiceCnt == voteNominationMax) { break; } } } } vote_addFiller() { if (g_choiceCnt == g_choiceMax) { return; } // grab the name of the filler file new filename[256]; get_pcvar_string(cvar_voteMapFile, filename, sizeof(filename)-1); // create an array of files that will be pulled from new fillerFile[8][256]; new mapsPerGroup[8], groupCnt; if (!equal(filename, "*")) { // determine what kind of file it's being used as new file = fopen(filename, "rt"); if (file) { new buffer[16]; fgets(file, buffer, sizeof(buffer)-1); trim(buffer); fclose(file); if (equali(buffer, "[groups]")) { dbg_log(8, " "); dbg_log(8, "this is a [groups] file"); // read the filler file to determine how many groups there are (max of 8) new groupIdx; file = fopen(filename, "rt"); while (!feof(file)) { fgets(file, buffer, sizeof(buffer)-1); trim(buffer); // dbg_log(8, "buffer: %s isdigit: %i groupCnt: %i ", buffer, isdigit(buffer[0]), groupCnt); if (isdigit(buffer[0])) { if (groupCnt < 8) { groupIdx = groupCnt++; mapsPerGroup[groupIdx] = str_to_num(buffer); formatex(fillerFile[groupIdx], sizeof(fillerFile[])-1, "%s/%i.ini", DIR_CONFIGS, groupCnt); // dbg_log(8, "fillerFile: %s", fillerFile[groupIdx]); } else { log_error(AMX_ERR_BOUNDS, "%L", LANG_SERVER, "GAL_GRP_FAIL_TOOMANY", filename); break; } } } fclose(file); if (groupCnt == 0) { log_error(AMX_ERR_GENERAL, "%L", LANG_SERVER, "GAL_GRP_FAIL_NOCOUNTS", filename); return; } } else { // we presume it's a listing of maps, ala mapcycle.txt copy(fillerFile[0], sizeof(filename)-1, filename); mapsPerGroup[0] = 8; groupCnt = 1; } } else { log_error(AMX_ERR_NOTFOUND, "%L", LANG_SERVER, "GAL_FILLER_NOTFOUND", fillerFile); } } else { // we'll be loading all maps in the /maps folder copy(fillerFile[0], sizeof(filename)-1, filename); mapsPerGroup[0] = 8; groupCnt = 1; } // fill remaining slots with random maps from each filler file, as much as possible new mapCnt, mapKey, allowedCnt, unsuccessfulCnt, choiceIdx, mapName[32]; for (new groupIdx = 0; groupIdx < groupCnt; ++groupIdx) { mapCnt = map_loadFillerList(fillerFile[groupIdx]); dbg_log(8, "[%i] groupCnt:%i mapCnt: %i g_choiceCnt: %i g_choiceMax: %i fillerFile: %s", groupIdx, groupCnt, mapCnt, g_choiceCnt, g_choiceMax, fillerFile[groupIdx]); if (g_choiceCnt < g_choiceMax && mapCnt) { unsuccessfulCnt = 0; allowedCnt = min(min(mapsPerGroup[groupIdx], g_choiceMax - g_choiceCnt), mapCnt); dbg_log(8, "[%i] allowedCnt: %i mapsPerGroup: %i Max-Cnt: %i", groupIdx, allowedCnt, mapsPerGroup[groupIdx], g_choiceMax - g_choiceCnt); for (choiceIdx = 0; choiceIdx < allowedCnt; ++choiceIdx) { mapKey = random_num(0, mapCnt - 1); ArrayGetString(g_fillerMap, mapKey, mapName, sizeof(mapName)-1); dbg_log(8, "[%i] choiceIdx: %i allowedCnt: %i mapKey: %i mapName: %s", groupIdx, choiceIdx, allowedCnt, mapKey, mapName); unsuccessfulCnt = 0; while ((map_isInMenu(mapName) || equal(g_currentMap, mapName) || map_isTooRecent(mapName) || prefix_isInMenu(mapName)) && unsuccessfulCnt < mapCnt) { unsuccessfulCnt++; if (++mapKey == mapCnt) { mapKey = 0; } ArrayGetString(g_fillerMap, mapKey, mapName, sizeof(mapName)-1); } if (unsuccessfulCnt == mapCnt) { //client_print(0, print_chat, "unsuccessfulCnt: %i mapCnt: %i", unsuccessfulCnt, mapCnt); // there aren't enough maps in this filler file to continue adding anymore break; } //client_print(0, print_chat, "mapIdx: %i map: %s", mapIdx, mapName); copy(g_mapChoice[g_choiceCnt++], sizeof(g_mapChoice[])-1, mapName); dbg_log(8, "[%i] mapName: %s unsuccessfulCnt: %i mapCnt: %i g_choiceCnt: %i", groupIdx, mapName, unsuccessfulCnt, mapCnt, g_choiceCnt); } } } } vote_loadChoices() { vote_addNominations(); vote_addFiller(); return g_choiceCnt; } vote_loadRunoffChoices() { new choiceCnt; new runoffChoice[2][MAX_MAPNAME_LEN+1]; copy(runoffChoice[0], sizeof(runoffChoice[])-1, g_mapChoice[g_runoffChoice[0]]); copy(runoffChoice[1], sizeof(runoffChoice[])-1, g_mapChoice[g_runoffChoice[1]]); new mapIdx; if (g_runoffChoice[0] != g_choiceCnt) { copy(g_mapChoice[mapIdx++], sizeof(g_mapChoice[])-1, runoffChoice[0]); choiceCnt++; } if (g_runoffChoice[1] != g_choiceCnt) { choiceCnt++; } copy(g_mapChoice[mapIdx], sizeof(g_mapChoice[])-1, runoffChoice[1]); g_choiceCnt = choiceCnt; return choiceCnt; } public vote_handleDisplay() { // announce: "time to choose" if (!(get_pcvar_num(cvar_soundsMute) & SOUND_TIMETOCHOOSE)) { client_cmd(0, "spk Gman/Gman_Choose%i", random_num(1, 2)); } if (g_voteStatus & VOTE_IS_RUNOFF) { g_voteDuration = get_pcvar_num(cvar_runoffDuration); } else { g_voteDuration = get_pcvar_num(cvar_voteDuration); } if (get_pcvar_num(cvar_voteStatus) && get_pcvar_num(cvar_voteStatusType) == SHOWSTATUSTYPE_PERCENTAGE) { copy(g_voteTallyType, sizeof(g_voteTallyType)-1, "%"); } if (get_cvar_num("gal_debug") & 4) { set_task(2.0, "dbg_fakeVotes"); } // make sure the display is contructed from scratch g_refreshVoteStatus = true; // ensure the vote status doesn't indicate expired g_voteStatus &= ~VOTE_HAS_EXPIRED; new arg[3]; arg[0] = true; arg[1] = 0; arg[2] = false; if (get_pcvar_num(cvar_voteStatus) == SHOWSTATUS_VOTE) { set_task(1.0, "vote_display", _, arg, sizeof(arg), "a", g_voteDuration); } else { set_task(1.0, "vote_display", _, arg, sizeof(arg)); } } public vote_display(arg[3]) { static allKeys = MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5|MENU_KEY_6|MENU_KEY_7|MENU_KEY_8|MENU_KEY_9|MENU_KEY_0; static keys, voteStatus[512], voteTally[16]; new updateTimeRemaining = arg[0]; new id = arg[1]; // dbg code ---- if (get_realplayersnum()) { new snuff = (id > 0) ? g_snuffDisplay[id] : -1; dbg_log(4, " [votedisplay()] id: %i updateTimeRemaining: %i unsnuffDisplay: %i g_snuffDisplay: %i g_refreshVoteStatus: %i g_choiceCnt: %i len(g_vote): %i len(voteStatus): %i", arg[1], arg[0], arg[2], snuff, g_refreshVoteStatus, g_choiceCnt, strlen(g_vote), strlen(voteStatus)); } if (id > 0 && g_snuffDisplay[id]) { new unsnuffDisplay = arg[2]; if (unsnuffDisplay) { g_snuffDisplay[id] = false; } else { return; } } new isVoteOver = (updateTimeRemaining == -1 && id == -1); new charCnt; if (g_refreshVoteStatus || isVoteOver) { // wipe the previous vote status clean voteStatus[0] = 0; keys = MENU_KEY_0; new voteCnt; new allowStay = (g_voteStatus & VOTE_IS_EARLY); new isRunoff = (g_voteStatus & VOTE_IS_RUNOFF); new bool:allowExtend = !allowStay && ((isRunoff && g_choiceCnt == 1) || (!(g_voteStatus & VOTE_FORCED) && !isRunoff && get_cvar_float("mp_timelimit") < get_pcvar_float(cvar_extendmapMax))); if (get_cvar_num("gal_debug") & 4) { allowExtend = !allowStay && ((isRunoff && g_choiceCnt == 1) || (!isRunoff && get_cvar_float("mp_timelimit") < get_pcvar_float(cvar_extendmapMax))); } // add the header if (isVoteOver) { charCnt = formatex(voteStatus, sizeof(voteStatus)-1, "%s%L^n", CLR_YELLOW, LANG_SERVER, "GAL_RESULT"); } else { charCnt = formatex(voteStatus, sizeof(voteStatus)-1, "%s%L^n", CLR_YELLOW, LANG_SERVER, "GAL_CHOOSE"); } // add maps to the menu for (new choiceIdx = 0; choiceIdx < g_choiceCnt; ++choiceIdx) { voteCnt = g_mapVote[choiceIdx]; vote_getTallyStr(voteTally, sizeof(voteTally)-1, voteCnt); charCnt += formatex(voteStatus[charCnt], sizeof(voteStatus)-1-charCnt, "^n%s%i. %s%s%s", CLR_RED, choiceIdx+1, CLR_WHITE, g_mapChoice[choiceIdx], voteTally); keys |= (1< } // add optional menu item if (allowExtend || allowStay) { // if it's not a runoff vote, add a space between the maps and the additional option if (g_voteStatus & VOTE_IS_RUNOFF == 0) { charCnt += formatex(voteStatus[charCnt], sizeof(voteStatus)-1-charCnt, "^n"); } vote_getTallyStr(voteTally, sizeof(voteTally)-1, g_mapVote[g_choiceCnt]); if (allowExtend) { // add the "Extend Map" menu item. charCnt += formatex(voteStatus[charCnt], sizeof(voteStatus)-1-charCnt, "^n%s%i. %s%L%s", CLR_RED, g_choiceCnt+1, CLR_WHITE, LANG_SERVER, "GAL_OPTION_EXTEND", g_currentMap, floatround(get_pcvar_float(cvar_extendmapStep)), voteTally); } else { // add the "Stay Here" menu item charCnt += formatex(voteStatus[charCnt], sizeof(voteStatus)-1-charCnt, "^n%s%i. %s%L%s", CLR_RED, g_choiceCnt+1, CLR_WHITE, LANG_SERVER, "GAL_OPTION_STAY", voteTally); } keys |= (1< } // make a copy of the virgin menu if (g_vote[0] == 0) { new cleanCharCnt = copy(g_vote, sizeof(g_vote)-1, voteStatus); // append a "None" option on for people to choose if they don't like any other choice formatex(g_vote[cleanCharCnt], sizeof(g_vote)-1-cleanCharCnt, "^n^n%s0. %s%L", CLR_RED, CLR_WHITE, LANG_SERVER, "GAL_OPTION_NONE"); } charCnt += formatex(voteStatus[charCnt], sizeof(voteStatus)-1-charCnt, "^n^n"); g_refreshVoteStatus = false; } static voteFooter[32]; if (updateTimeRemaining && get_pcvar_num(cvar_voteExpCountdown)) { charCnt = copy(voteFooter, sizeof(voteFooter)-1, "^n^n"); if (--g_voteDuration <= 10) { formatex(voteFooter[charCnt], sizeof(voteFooter)-1-charCnt, "%s%L: %s%i", CLR_GREY, LANG_SERVER, "GAL_TIMELEFT", CLR_RED, g_voteDuration); } } // create the different displays static menuClean[512], menuDirty[512]; menuClean[0] = 0; menuDirty[0] = 0; formatex(menuClean, sizeof(menuClean)-1, "%s%s", g_vote, voteFooter); if (!isVoteOver) { formatex(menuDirty, sizeof(menuDirty)-1, "%s%s", voteStatus, voteFooter); } else { formatex(menuDirty, sizeof(menuDirty)-1, "%s^n^n%s%L", voteStatus, CLR_YELLOW, LANG_SERVER, "GAL_VOTE_ENDED"); } new menuid, menukeys; // display the vote new showStatus = get_pcvar_num(cvar_voteStatus); if (id > 0) { // optionally display to single player that just voted if (showStatus == SHOWSTATUS_VOTE) { // dbg code ---- new name[32]; get_user_name(id, name, 31); dbg_log(4, " [%s (dirty, just voted)]", name); dbg_log(4, " %s", menuDirty); //-------------- get_user_menu(id, menuid, menukeys); if (menuid == 0 || menuid == g_menuChooseMap) { show_menu(id, allKeys, menuDirty, max(1, g_voteDuration), MENU_CHOOSEMAP); } } } else { // display to everyone new players[32], playerCnt; get_players(players, playerCnt, "ch"); // skip bots and hltv for (new playerIdx = 0; playerIdx < playerCnt; ++playerIdx) { id = players[playerIdx]; if (g_voted[id] == false && !isVoteOver) { // dbg code ---- if (playerIdx == 0) { new name[32]; get_user_name(id, name, 31); dbg_log(4, " [%s (clean)]", name); dbg_log(4, " %s", menuClean); } //-------------- get_user_menu(id, menuid, menukeys); if (menuid == 0 || menuid == g_menuChooseMap) { show_menu(id, keys, menuClean, g_voteDuration, MENU_CHOOSEMAP); } } else { if ((isVoteOver && showStatus) || (showStatus == SHOWSTATUS_VOTE && g_voted[id])) { // dbg code ---- if (playerIdx == 0) { new name[32]; get_user_name(id, name, 31); dbg_log(4, " [%s (dirty)]", name); dbg_log(4, " %s", menuDirty); } //-------------- get_user_menu(id, menuid, menukeys); if (menuid == 0 || menuid == g_menuChooseMap) { show_menu(id, allKeys, menuDirty, (isVoteOver) ? 5 : max(1, g_voteDuration), MENU_CHOOSEMAP); } } } // dbg code ---- if (id == 1) { dbg_log(4, ""); } //-------------- } } } vote_getTallyStr(voteTally[], voteTallyLen, voteCnt) { if (voteCnt && get_pcvar_num(cvar_voteStatusType) == SHOWSTATUSTYPE_PERCENTAGE) { voteCnt = percent(voteCnt, g_votesCast); } if (get_pcvar_num(cvar_voteStatus) && voteCnt) { formatex(voteTally, voteTallyLen, " %s(%i%s)", CLR_GREY, voteCnt, g_voteTallyType); } else { voteTally[0] = 0; } } public vote_expire() { g_voteStatus |= VOTE_HAS_EXPIRED; // dbg code ---- if (get_realplayersnum()) { dbg_log(4, ""); dbg_log(4, " [VOTE RESULT]"); new voteTally[16]; for (new idxChoice = 0; idxChoice <= g_choiceCnt; ++idxChoice) { vote_getTallyStr(voteTally, sizeof(voteTally)-1, g_mapVote[idxChoice]); dbg_log(4, " %2i/%3i %i. %s", g_mapVote[idxChoice], voteTally, idxChoice, g_mapChoice[idxChoice]); } dbg_log(4, ""); } //-------------- g_vote[0] = 0; // determine the number of votes for 1st and 2nd place new firstPlaceVoteCnt, secondPlaceVoteCnt, totalVotes; for (new idxChoice = 0; idxChoice <= g_choiceCnt; ++idxChoice) { totalVotes += g_mapVote[idxChoice]; if (firstPlaceVoteCnt < g_mapVote[idxChoice]) { secondPlaceVoteCnt = firstPlaceVoteCnt; firstPlaceVoteCnt = g_mapVote[idxChoice]; } else if (secondPlaceVoteCnt < g_mapVote[idxChoice]) { secondPlaceVoteCnt = g_mapVote[idxChoice]; } } // determine which maps are in 1st and 2nd place new firstPlace[MAX_MAPS_IN_VOTE + 1], firstPlaceCnt; new secondPlace[MAX_MAPS_IN_VOTE + 1], secondPlaceCnt; for (new idxChoice = 0; idxChoice <= g_choiceCnt; ++idxChoice) { if (g_mapVote[idxChoice] == firstPlaceVoteCnt) { firstPlace[firstPlaceCnt++] = idxChoice; } else if (g_mapVote[idxChoice] == secondPlaceVoteCnt) { secondPlace[secondPlaceCnt++] = idxChoice; } } // announce the outcome new idxWinner; if (firstPlaceVoteCnt) { // start a runoff vote, if needed if (get_pcvar_num(cvar_runoffEnabled) && !(g_voteStatus & VOTE_IS_RUNOFF)) { // if the top vote getting map didn't receive over 50% of the votes cast, start runoff vote if (firstPlaceVoteCnt <= totalVotes / 2) { // announce runoff voting requirement client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_RUNOFF_REQUIRED"); if (!(get_pcvar_num(cvar_soundsMute) & SOUND_RUNOFFREQUIRED)) { client_cmd(0, "spk ^"run officer(e40) voltage(e30) accelerating(s70) is required^""); } // let the server know the next vote will be a runoff g_voteStatus |= VOTE_IS_RUNOFF; // determine the two choices that will be facing off new choice1Idx, choice2Idx; if (firstPlaceCnt > 2) { choice1Idx = random_num(0, firstPlaceCnt - 1); choice2Idx = random_num(0, firstPlaceCnt - 1); if (choice2Idx == choice1Idx) { choice2Idx = (choice2Idx == firstPlaceCnt - 1) ? 0 : ++choice2Idx; } g_runoffChoice[0] = firstPlace[choice1Idx]; g_runoffChoice[1] = firstPlace[choice2Idx]; client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_RESULT_TIED1", firstPlaceCnt); } else if (firstPlaceCnt == 2) { g_runoffChoice[0] = firstPlace[0]; g_runoffChoice[1] = firstPlace[1]; } else if (secondPlaceCnt == 1) { g_runoffChoice[0] = firstPlace[0]; g_runoffChoice[1] = secondPlace[0]; } else { g_runoffChoice[0] = firstPlace[0]; g_runoffChoice[1] = secondPlace[random_num(0, secondPlaceCnt - 1)]; client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_RESULT_TIED2", secondPlaceCnt); } /* // dbg new dbg1 = g_runoffChoice[0]; new dbg2 = g_runoffChoice[1]; client_print(0, print_chat, "%s, %s", g_mapChoice[dbg1], g_mapChoice[dbg2]); */ // clear all the votes vote_resetStats(); // start the runoff vote set_task(5.0, "vote_startDirector"); return; } } // if there is a tie for 1st, randomly select one as the winner if (firstPlaceCnt > 1) { idxWinner = firstPlace[random_num(0, firstPlaceCnt - 1)]; client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_WINNER_TIED", firstPlaceCnt); } else { idxWinner = firstPlace[0]; } if (idxWinner == g_choiceCnt) { if (get_pcvar_num(cvar_endOfMapVote)) { new nextMap[32]; formatex(nextMap, sizeof(nextMap)-1, "%L", LANG_SERVER, "GAL_NEXTMAP_UNKNOWN"); map_setNext(nextMap); } // restart map end vote task g_pauseMapEndVoteTask = false; if (g_voteStatus & VOTE_IS_EARLY) { // "stay here" won client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_WINNER_STAY"); // clear all the votes vote_resetStats(); // no longer is an early vote g_voteStatus &= ~VOTE_IS_EARLY; } else { // "extend map" won client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_WINNER_EXTEND", floatround(get_pcvar_float(cvar_extendmapStep))); map_extend(); } } else { map_setNext(g_mapChoice[idxWinner]); server_exec(); client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_NEXTMAP", g_mapChoice[idxWinner]); g_voteStatus |= VOTE_IS_OVER; } } else { // nobody voted. pick a random map from the choices provided. idxWinner = random_num(0, g_choiceCnt - 1); map_setNext(g_mapChoice[idxWinner]); client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_WINNER_RANDOM", g_mapChoice[idxWinner]); g_voteStatus |= VOTE_IS_OVER; } g_refreshVoteStatus = true; new playerCnt = get_realplayersnum(); // vote is no longer in progress g_voteStatus &= ~VOTE_IN_PROGRESS; if (g_handleMapChange) { if ((g_voteStatus & VOTE_FORCED || (playerCnt == 1 && idxWinner < g_choiceCnt) || playerCnt == 0) && !(get_cvar_num("gal_debug") & 4)) { // tell the map we need to finish up set_task(2.0, "map_manageEnd"); } else { // restart map end task g_pauseMapEndManagerTask = false; } } } map_extend() { dbg_log(2, "%32s mp_timelimit: %f g_rtvWait: %f extendmapStep: %f", "map_extend(in)", get_cvar_float("mp_timelimit"), g_rtvWait, get_pcvar_float(cvar_extendmapStep)); // reset the "rtv wait" time, taking into consideration the map extension if (g_rtvWait) { g_rtvWait = get_cvar_float("mp_timelimit") + g_rtvWait; } // do that actual map extension set_cvar_float("mp_timelimit", get_cvar_float("mp_timelimit") + get_pcvar_float(cvar_extendmapStep)); server_exec(); // clear vote stats vote_resetStats(); // if we were in a runoff mode, get out of it g_voteStatus &= ~VOTE_IS_RUNOFF; dbg_log(2, "%32s mp_timelimit: %f g_rtvWait: %f extendmapStep: %f", "map_extend(out)", get_cvar_float("mp_timelimit"), g_rtvWait, get_pcvar_float(cvar_extendmapStep)); } vote_resetStats() { // g_vote[0] = 0; g_votesCast = 0; arrayset(g_mapVote, 0, MAX_MAPS_IN_VOTE + 1); // reset everyones' rocks arrayset(g_rockedVote, false, sizeof(g_rockedVote)); g_rockedVoteCnt = 0; // reset everyones' votes // arrayset(g_voted, false, sizeof(g_voted)); } map_isInMenu(map[]) { for (new idxChoice = 0; idxChoice < g_choiceCnt; ++idxChoice) { if (equal(map, g_mapChoice[idxChoice])) { return true; } } return false; } prefix_isInMenu(map[]) { if (get_pcvar_num(cvar_voteUniquePrefixes)) { new tentativePrefix[8], existingPrefix[8], junk[8]; strtok(map, tentativePrefix, sizeof(tentativePrefix)-1, junk, sizeof(junk)-1, '_', 1); for (new idxChoice = 0; idxChoice < g_choiceCnt; ++idxChoice) { strtok(g_mapChoice[idxChoice], existingPrefix, sizeof(existingPrefix)-1, junk, sizeof(junk)-1, '_', 1); if (equal(tentativePrefix, existingPrefix)) { return true; } } } return false; } map_isTooRecent(map[]) { if (get_pcvar_num(cvar_banRecent)) { for (new idxBannedMap = 0; idxBannedMap < g_cntRecentMap; ++idxBannedMap) { if (equal(map, g_recentMap[idxBannedMap])) { return true; } } } return false; } public vote_handleChoice(id, key) { if (g_voteStatus & VOTE_HAS_EXPIRED) { client_cmd(id, "^"slot%i^"", key + 1); return; } g_snuffDisplay[id] = true; if (g_voted[id] == false) { new name[32]; if (get_pcvar_num(cvar_voteAnnounceChoice)) { get_user_name(id, name, sizeof(name)-1); } // dbg code ---- get_user_name(id, name, sizeof(name)-1); //-------------- // confirm the player's choice if (key == 9) { dbg_log(4, " %-32s (none)", name); if (get_pcvar_num(cvar_voteAnnounceChoice)) { client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_CHOICE_NONE_ALL", name); } else { client_print(id, print_chat, "%L", id, "GAL_CHOICE_NONE"); } } else { // increment votes cast count g_votesCast++; if (key == g_choiceCnt) { // only display the "none" vote if we haven't already voted (we can make it here from the vote status menu too) if (g_voted[id] == false) { dbg_log(4, " %-32s (extend)", name); if (get_pcvar_num(cvar_voteAnnounceChoice)) { client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_CHOICE_EXTEND_ALL", name); } else { client_print(id, print_chat, "%L", id, "GAL_CHOICE_EXTEND"); } } } else { dbg_log(4, " %-32s %s", name, g_mapChoice[key]); if (get_pcvar_num(cvar_voteAnnounceChoice)) { client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_CHOICE_MAP_ALL", name, g_mapChoice[key]); } else { client_print(id, print_chat, "%L", id, "GAL_CHOICE_MAP", g_mapChoice[key]); } } // register the player's choice giving extra weight to admin votes new voteWeight = get_pcvar_num(cvar_voteWeight); if (voteWeight > 1 && has_flag(id, g_voteWeightFlags)) { g_mapVote[key] += voteWeight; g_votesCast += (voteWeight - 1); client_print(id, print_chat, "%L", id, "GAL_VOTE_WEIGHTED", voteWeight); } else { g_mapVote[key]++; } } g_voted[id] = true; g_refreshVoteStatus = true; } else { client_cmd(id, "^"slot%i^"", key + 1); } // display the vote again, with status if (get_pcvar_num(cvar_voteStatus) == SHOWSTATUS_VOTE) { new arg[3]; arg[0] = false; arg[1] = id; arg[2] = true; set_task(0.1, "vote_display", _, arg, sizeof(arg)); //vote_display(arg); } } public map_change() { // restore the map's timelimit, just in case we had changed it map_restoreOriginalTimeLimit(); // grab the name of the map we're changing to new map[MAX_MAPNAME_LEN + 1]; get_cvar_string("amx_nextmap", map, sizeof(map)-1); // verify we're changing to a valid map if (!is_map_valid(map)) { // probably admin did something dumb like changed the map time limit below // the time remaining in the map, thus making the map over immediately. // since the next map is unknown, just restart the current map. copy(map, sizeof(map)-1, g_currentMap); } // change to the map server_cmd("changelevel %s", map); } Float:map_getMinutesElapsed() { dbg_log(2, "%32s mp_timelimit: %f", "map_getMinutesElapsed(in/out)", get_cvar_float("mp_timelimit")); return get_cvar_float("mp_timelimit") - (float(get_timeleft()) / 60.0); } public vote_rock(id) { // if an early vote is pending, don't allow any rocks if (g_voteStatus & VOTE_IS_EARLY) { client_print(id, print_chat, "%L", id, "GAL_ROCK_FAIL_PENDINGVOTE"); return; } new Float:minutesElapsed = map_getMinutesElapsed(); // if the player is the only one on the server, bring up the vote immediately if (get_realplayersnum() == 1 && minutesElapsed > floatmin(2.0, g_rtvWait)) { vote_startDirector(true); return; } // make sure enough time has gone by on the current map if (g_rtvWait) { if (minutesElapsed < g_rtvWait) { client_print(id, print_chat, "%L", id, "GAL_ROCK_FAIL_TOOSOON", floatround(g_rtvWait - minutesElapsed, floatround_ceil)); return; } } // rocks can only be made if a vote isn't already in progress if (g_voteStatus & VOTE_IN_PROGRESS) { client_print(id, print_chat, "%L", id, "GAL_ROCK_FAIL_INPROGRESS"); return; } // and if the outcome of the vote hasn't already been determined else if (g_voteStatus & VOTE_IS_OVER) { client_print(id, print_chat, "%L", id, "GAL_ROCK_FAIL_VOTEOVER"); return; } // determine how many total rocks are needed new rocksNeeded = vote_getRocksNeeded(); // make sure player hasn't already rocked the vote if (g_rockedVote[id]) { client_print(id, print_chat, "%L", id, "GAL_ROCK_FAIL_ALREADY", rocksNeeded - g_rockedVoteCnt); rtv_remind(TASKID_REMINDER + id); return; } // allow the player to rock the vote g_rockedVote[id] = true; client_print(id, print_chat, "%L", id, "GAL_ROCK_SUCCESS"); // make sure the rtv reminder timer has stopped if (task_exists(TASKID_REMINDER)) { remove_task(TASKID_REMINDER); } // determine if there have been enough rocks for a vote yet if (++g_rockedVoteCnt >= rocksNeeded) { // announce that the vote has been rocked client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_ROCK_ENOUGH"); // start up the vote director vote_startDirector(true); } else { // let the players know how many more rocks are needed rtv_remind(TASKID_REMINDER); if (get_pcvar_num(cvar_rtvReminder)) { // initialize the rtv reminder timer to repeat how many rocks are still needed, at regular intervals set_task(get_pcvar_float(cvar_rtvReminder) * 60.0, "rtv_remind", TASKID_REMINDER, _, _, "b"); } } } vote_unrock(id) { if (g_rockedVote[id]) { g_rockedVote[id] = false; g_rockedVoteCnt--; // and such } } vote_getRocksNeeded() { return floatround(get_pcvar_float(cvar_rtvRatio) * float(get_realplayersnum()), floatround_ceil); } public rtv_remind(param) { new who = param - TASKID_REMINDER; // let the players know how many more rocks are needed client_print(who, print_chat, "%L", LANG_PLAYER, "GAL_ROCK_NEEDMORE", vote_getRocksNeeded() - g_rockedVoteCnt); } public cmd_listmaps(id) { // new arg1[8]; // new start = read_argv(1, arg1, 7) ? str_to_num(arg1) : 1; map_listAll(id); return PLUGIN_HANDLED; } public cmd_HL1_votemap(id) { if (get_pcvar_num(cvar_cmdVotemap) == 0) { con_print(id, "%L", id, "GAL_DISABLED"); return PLUGIN_HANDLED; } return PLUGIN_CONTINUE; } public cmd_HL1_listmaps(id) { switch (get_pcvar_num(cvar_cmdListmaps)) { case 0: { con_print(id, "%L", id, "GAL_DISABLED"); } case 2: { map_listAll(id); } default: { return PLUGIN_CONTINUE; } } return PLUGIN_HANDLED; } map_listAll(id) { static lastMapDisplayed[MAX_PLAYER_CNT + 1][2]; // determine if the player has requested a listing before new userid = get_user_userid(id); if (userid != lastMapDisplayed[id][listMAPS_USERID]) { lastMapDisplayed[id][listMAPS_USERID] = 0; } new command[32]; read_argv(0, command, sizeof(command)-1); new arg1[8], start; new mapCount = get_pcvar_num(cvar_listmapsPaginate); if (mapCount) { if (read_argv(1, arg1, sizeof(arg1)-1)) { if (arg1[0] == '*') { // if the last map previously displayed belongs to the current user, // start them off there, otherwise, start them at 1 if (lastMapDisplayed[id][listMAPS_USERID]) { start = lastMapDisplayed[id][listMAPS_LAST] + 1; } else { start = 1; } } else { start = str_to_num(arg1); } } else { start = 1; } if (id == 0 && read_argc() == 3 && read_argv(2, arg1, sizeof(arg1)-1)) { mapCount = str_to_num(arg1); } } if (start < 1) { start = 1; } if (start >= g_nominationMapCnt) { start = g_nominationMapCnt - 1; } new end = mapCount ? start + mapCount - 1 : g_nominationMapCnt; if (end > g_nominationMapCnt) { end = g_nominationMapCnt; } // this enables us to use 'command *' to get the next group of maps, when paginated lastMapDisplayed[id][listMAPS_USERID] = userid; lastMapDisplayed[id][listMAPS_LAST] = end - 1; con_print(id, "^n----- %L -----", id, "GAL_LISTMAPS_TITLE", g_nominationMapCnt); new nominated[64], nominator_id, name[32], mapName[32], idx; for (idx = start - 1; idx < end; idx++) { nominator_id = nomination_getPlayer(idx); if (nominator_id) { get_user_name(nominator_id, name, sizeof(name)-1); formatex(nominated, sizeof(nominated)-1, "%L", id, "GAL_NOMINATEDBY", name); } else { nominated[0] = 0; } ArrayGetString(g_nominationMap, idx, mapName, sizeof(mapName)-1); con_print(id, "%3i: %s %s", idx + 1, mapName, nominated); } if (mapCount && mapCount < g_nominationMapCnt) { con_print(id, "----- %L -----", id, "GAL_LISTMAPS_SHOWING", start, idx, g_nominationMapCnt); if (end < g_nominationMapCnt) { con_print(id, "----- %L -----", id, "GAL_LISTMAPS_MORE", command, end + 1, command); } } } /* map_listMatches(id, match[]) { strtolower(match); con_print(id, "%L", id, "GAL_MATCHING", match); con_print(id, "------------------------------------------"); new mapName[32], matchCnt; new nominated[64], nominator_id, name[32]; for (new idx = 1; idx <= g_nominationMapCnt; ++idx) { copy(mapName, sizeof(mapName)-1, g_nominationMap[idx]); strtolower(mapName); if (containi(mapName, match) > -1) { nominator_id = nomination_getPlayer(idx); if (nominator_id) { get_user_name(nominator_id, name, sizeof(name)-1); formatex(nominated, sizeof(nominated)-1, "(nominated by %s)", name); } else { nominated[0] = 0; } con_print(id, "%3i: %s %s", ++matchCnt, g_nominationMap[idx], nominated); } } } */ con_print(id, message[], {Float,Sql,Result,_}:...) { new consoleMessage[256]; vformat(consoleMessage, sizeof(consoleMessage)-1, message, 3); if (id) { new authid[32]; get_user_authid(id, authid, 31); if (!equal(authid, "STEAM_ID_LAN")) { console_print(id, consoleMessage); return; } } server_print(consoleMessage); } public client_disconnect(id) { g_voted[id] = false; // un-rock the vote vote_unrock(id); // cancel player's nominations new playerNominationMax = min(get_pcvar_num(cvar_nomPlayerAllowance), MAX_NOMINATION_CNT); new nominatedMaps[256], nominationCnt, idxMap, mapName[32]; for (new idxNomination = 1; idxNomination <= playerNominationMax; ++idxNomination) { idxMap = g_nomination[id][idxNomination]; if (idxMap >= 0) { ArrayGetString(g_nominationMap, idxMap, mapName, sizeof(mapName)-1); nominationCnt++; format(nominatedMaps, sizeof(nominatedMaps)-1, "%s%s, ", nominatedMaps, mapName); g_nomination[id][idxNomination] = -1; } } if (nominationCnt) { // strip the extraneous ", " from the string nominatedMaps[strlen(nominatedMaps) - 2] = 0; // inform the masses that the maps are no longer nominated nomination_announceCancellation(nominatedMaps); } new dbg_playerCnt = get_realplayersnum()-1; dbg_log(2, "%32s dbg_playerCnt:%i", "client_disconnect()", dbg_playerCnt); if (dbg_playerCnt == 0) { srv_handleEmpty(); } } public client_connect(id) { set_pcvar_num(cvar_emptyCycle, 0); vote_unrock(id); } public client_putinserver(id) { if ((g_voteStatus & VOTE_IS_EARLY) && !is_user_bot(id) && !is_user_hltv(id)) { set_task(20.0, "srv_announceEarlyVote", id); } } srv_handleEmpty() { dbg_log(2, "%32s mp_timelimit: %f g_originalTimelimit: %f", "srv_handleEmpty(in)", get_cvar_float("mp_timelimit"), g_originalTimelimit); if (g_originalTimelimit != get_cvar_float("mp_timelimit")) { // it's possible that the map has been extended at least once. that // means that if someone comes into the server, the time limit will // be the extended time limit rather than the normal time limit. bad. // reset the original time limit map_restoreOriginalTimeLimit(); } // might be utilizing "empty server" feature if (g_isUsingEmptyCycle && g_emptyMapCnt) { srv_startEmptyCountdown(); } dbg_log(2, "%32s mp_timelimit: %f g_originalTimelimit: %f", "srv_handleEmpty(out)", get_cvar_float("mp_timelimit"), g_originalTimelimit); } public srv_announceEarlyVote(id) { if (is_user_connected(id)) { //client_print(id, print_chat, "%L", id, "GAL_VOTE_EARLY"); new text[101]; formatex(text, sizeof(text)-1, "^x04%L", id, "GAL_VOTE_EARLY"); print_color(id, text); } } public srv_initEmptyCheck() { if (get_pcvar_num(cvar_emptyWait)) { if ((get_realplayersnum()) == 0 && !get_pcvar_num(cvar_emptyCycle)) { srv_startEmptyCountdown(); } g_isUsingEmptyCycle = true; } } srv_startEmptyCountdown() { new waitMinutes = get_pcvar_num(cvar_emptyWait); if (waitMinutes) { set_task(float(waitMinutes * 60), "srv_startEmptyCycle", TASKID_EMPTYSERVER); } } public srv_startEmptyCycle() { set_pcvar_num(cvar_emptyCycle, 1); // set the next map from the empty cycle list, // or the first one, if the current map isn't part of the cycle new nextMap[32], mapIdx; mapIdx = map_getNext(g_emptyCycleMap, g_currentMap, nextMap); map_setNext(nextMap); // if the current map isn't part of the empty cycle, // immediately change to next map that is if (mapIdx == -1) { map_change(); } } nomination_announceCancellation(nominations[]) { client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_CANCEL_SUCCESS", nominations); } nomination_clearAll() { for (new idxPlayer = 1; idxPlayer <= MAX_PLAYER_CNT; idxPlayer++) { for (new idxNomination = 1; idxNomination <= MAX_NOMINATION_CNT; idxNomination++) { g_nomination[idxPlayer][idxNomination] = -1; } } g_nominationCnt = 0; } map_announceNomination(id, map[]) { new name[32]; get_user_name(id, name, sizeof(name)-1); client_print(0, print_chat, "%L", LANG_PLAYER, "GAL_NOM_SUCCESS", name, map); } #if AMXX_VERSION_NUM < 180 has_flag(id, flags[]) { return (get_user_flags(id) & read_flags(flags)); } #endif public sort_stringsi(const elem1[], const elem2[], const array[], data[], data_size) { return strcmp(elem1, elem2, 1); } stock get_realplayersnum() { new players[32], playerCnt; get_players(players, playerCnt, "ch"); return playerCnt; } stock percent(is, of) { return (of != 0) ? floatround(floatmul(float(is)/float(of), 100.0)) : 0; } print_color(id, text[]) { message_begin(MSG_ONE, get_user_msgid("SayText"), {0, 0, 0}, id); write_byte(id); write_string(text); message_end(); } map_restoreOriginalTimeLimit() { dbg_log(2, "%32s mp_timelimit: %f g_originalTimelimit: %f", "map_restoreOriginalTimeLimit(in)", get_cvar_float("mp_timelimit"), g_originalTimelimit); if (g_originalTimelimit != TIMELIMIT_NOT_SET) { server_cmd("mp_timelimit %f", g_originalTimelimit); server_exec(); } dbg_log(2, "%32s mp_timelimit: %f g_originalTimelimit: %f", "map_restoreOriginalTimeLimit(out)", get_cvar_float("mp_timelimit"), g_originalTimelimit); } dbg_log(const mode, const text[] = "", {Float,Sql,Result,_}:...) { new dbg = get_cvar_num("gal_debug"); if (mode & dbg) { // format the text as needed new formattedText[1024]; format_args(formattedText, 1023, 1); // grab the current game time new Float:gameTime = get_gametime(); // log text to file log_to_file("_galileo.log", "{%3.4f} %s", gameTime, formattedText); if (dbg & 1 && formattedText[0]) { // make quotes in log text palatable to 3rd party chat log viewers new isFound = 1; while (isFound) isFound = replace(formattedText, 1023, "^"", "'"); // print to the server log so as to be picked up by programs such as HLSW log_message("^"<><><>^" triggered ^"amx_chat^" (text ^"[GAL] %s^")", formattedText); } } // not needed but gets rid of stupid compiler error if (text[0] == 0) return; } Nose porque no me anda, :S supuestamente es el votemap con % pero no me anda espero que el que lo vea , se fije en el error yo no lo vi, Gracias
  20. Bill Gates fue un Hacker? Sáb, 07/23/2005 - 23:59 La mayoría de usuarios en todo el mundo consideran a Bill Gates o a Microsoft como autores del D.O.S. y el MS-DOS. Pero la historia nos revela la verdad. En 1980 la IBM Corporation decidió ingresar al mercado de las computadoras personales, y fue tal su prisa que primero desarrolló su arquitectura de hardware, para después buscar el sistema operativo con el cual dichos equipos debían ejecutarse. Pensaron en primer lugar en Gary Kildall, fundador de la Digital Research Inc. y autor del sistema operativo CP/M muy vigente por aquella época. Con criterio especulativo, Kildall viajó a Florida en compañía de su esposa y se dedicó a divertirse, realizar vuelos en avioneta, etc. y no atendía las desesperadas llamadas telefónicas de los directores de la IBM. Enterado de esta situación Bill Gates acudió a una empresa llamada Seattle Computer Products, para la cual trabajaba el Ing. Tim Paterson, quien había desarrollado un "clone" del sistema operativo CP/M, el cual evidentemente había sido desensamblado y alterado, al que denominó Quick and Dirty D.O.S o QDOS. En 1981 Microsoft, adquirió los "derechos de autor" de este sistema operativo, por US $ 50,000 y contrató al Ing. Tim Paterson, su autor, para que trabajase 4 días a la semana, con el objeto de que realizara "algunos cambios", para poder "transformar" al sistema. Este mismo producto "mejorado" por Microsoft, fue vendido a la IBM Corporation, bajo el nombre de PC-DOS y Microsoft se reservó el derecho de poder comercializarlo bajo el nombre de MS-DOS. Fuente: Perantivirus.com
  21. FAKE.- (10 character)
  22. Nivel X By Marito Baracus YAPA:
  23. giulix

    Preguntale a Chri.is

    porque tenes un tag tan feo ? :lloron:
×
×
  • Crear nuevo...

Información importante

Al utilizar nuestra web, aceptas nuestras Política de privacidad estás de acuerdo con las condiciones establecidas.