mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-10-18 11:18:30 +00:00
Merge branch 'coop' into coopnet
This commit is contained in:
commit
6c7e7778d1
69 changed files with 563 additions and 290 deletions
|
@ -11522,7 +11522,7 @@ MAX_LOCAL_VERSION_LENGTH = 12
|
|||
MAX_VERSION_LENGTH = 10
|
||||
|
||||
--- @type integer
|
||||
MINOR_VERSION_NUMBER = 0
|
||||
MINOR_VERSION_NUMBER = 1
|
||||
|
||||
--- @type integer
|
||||
PATCH_VERSION_NUMBER = 0
|
||||
|
|
|
@ -222,8 +222,12 @@ function djui_hud_render_texture_tile_interpolated(texInfo, prevX, prevY, prevSc
|
|||
end
|
||||
|
||||
--- @param levelNum number
|
||||
--- @param func fun(areaNum:number, bhv:table)
|
||||
--- @param func fun(areaIndex:number, bhvData:table, macroBhvIds:table, macroBhvArgs:table)
|
||||
--- @return nil
|
||||
--- When `func` is called, arguments are filled depending on the level command:
|
||||
--- - `AREA` command: only `areaIndex` is filled. It's a number.
|
||||
--- - `OBJECT` command: only `bhvData` is filled. `bhvData` is a table with two fields: `behavior` and `behaviorArg`.
|
||||
--- - `MACRO` command: only `macroBhvIds` and `macroBhvArgs` are filled. `macrobhvIds` is a list of behavior ids. `macroBhvArgs` is a list of behavior params. Both lists have the same size and start at index 0.
|
||||
function level_script_parse(levelNum, func)
|
||||
-- ...
|
||||
end
|
||||
|
|
186
lang/Spanish.ini
186
lang/Spanish.ini
|
@ -2,47 +2,47 @@
|
|||
CONNECTED = "@ se ha conectado"
|
||||
DISCONNECTED = "@ se ha desconectado"
|
||||
LEFT_THIS_LEVEL = "@ ha salido del nivel"
|
||||
ENTERED_THIS_LEVEL = "@ ha entrado al nivel"
|
||||
ENTERED = "@ se ha unido\n#"
|
||||
SERVER_CLOSED = "\\#ffa0a0\\Desconectado:\\#dcdcdc\\ servidor cerrado"
|
||||
ENTERED_THIS_LEVEL = "@ se ha unido a tu nivel"
|
||||
ENTERED = "@ ha entrado a \n#"
|
||||
SERVER_CLOSED = "\\#ffa0a0\\Desconectado:\\#dcdcdc\\ El servidor ha sido cerrado."
|
||||
DISCORD_ERROR = "Discord ha lanzado un error.\nPara solucionarlo, intenta: \n1. Cerrar el juego.\n2. Reiniciar Discord.\n3. Iniciar el juego."
|
||||
DISCORD_DETECT = "\\#ffa0a0\\Error:\\#c8c8c8\\ No se ha podido detectar Discord.\n\\#a0a0a0\\Prueba a cerrar el juego, reiniciar Discord, e iniciar el juego otra vez."
|
||||
DISCONNECT_FULL = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ La partida está llena."
|
||||
DISCONNECT_KICK = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ Has sido expulsado del servidor."
|
||||
DISCONNECT_BAN = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ Has sido vetado del servidor."
|
||||
DISCONNECT_REJOIN = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ Uniendose de nuevo..."
|
||||
DISCONNECT_CLOSED = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ El anfitrión ha cerrado la conexion."
|
||||
DISCONNECT_BIG_MOD = "El servidor tenía un mod demasiado pesado.\nSaliendo."
|
||||
DIED = "@ ha muerto"
|
||||
DEBUG_FLY = "@ está en estado de vuelo libre debug"
|
||||
IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Mod \n\\#c8c8c8\\'@'\n\\#a0ffa0\\Importado"
|
||||
IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\DynOS pack \n\\#c8c8c8\\'@'\n\\#a0ffa0\\Importado"
|
||||
IMPORT_FAIL = "\\#ffa0a0\\Fallo al importar \\#c8c8c8\\\n'@'"
|
||||
IMPORT_FAIL_INGAME = "\\#ffa0a0\\No se puede importar mientras se está en juego"
|
||||
DISCONNECT_FULL = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ La partida está llena"
|
||||
DISCONNECT_KICK = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ has sido\nexpulsado del servidor"
|
||||
DISCONNECT_BAN = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ has sido\nbaneado del servidor"
|
||||
DISCONNECT_REJOIN = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ Uniéndose de nuevo..."
|
||||
DISCONNECT_CLOSED = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ El alfitrión ha cerrado el servidor"
|
||||
DISCONNECT_BIG_MOD = "\\#ffa0a0\\Desconectado:\\#c8c8c8\\ El servidor tenía\nun mod demasiado pesado"
|
||||
DIED = "@ ha muerto."
|
||||
DEBUG_FLY = "@ Está en estado de vuelo libre debug."
|
||||
IMPORT_MOD_SUCCESS = "El mod \\#c8c8c8\\'@'\\#a0ffa0\\\nha sido importado con éxito."
|
||||
IMPORT_DYNOS_SUCCESS = "El pack de DynOS \\#c8c8c8\\'@'\\#a0ffa0\\\nha sido importado con éxito."
|
||||
IMPORT_FAIL = "\n\\#ffa0a0\\Error al importar archivo. \\#c8c8c8\\\n'@'"
|
||||
IMPORT_FAIL_INGAME = "\\#ffa0a0\\No se pueden importar archivos\nen medio de una partida."
|
||||
|
||||
[CHAT]
|
||||
KICKING = "¡Expulsando a '@'!"
|
||||
BANNING = "¡Vetando a '@'!"
|
||||
SERVER_ONLY = "Solo el servidor puede usar este comando."
|
||||
PERM_BANNING = "¡Vetando permanentemente a '@'!"
|
||||
ADD_MODERATOR = "¡Añadiendo a '@' como Moderador!"
|
||||
KICKING = "¡'@' ha sido expulsado!"
|
||||
BANNING = "¡'@' ha sido baneado!"
|
||||
SERVER_ONLY = "Solo el anfitrión puede usar este comando."
|
||||
PERM_BANNING = "¡'@' ha sido baneado permanentemente!"
|
||||
ADD_MODERATOR = "¡'@' ahora es un moderador!"
|
||||
PLAYERS = "Jugadores"
|
||||
NO_PERMS = "No tienes permiso para usar este comando."
|
||||
PLAYER_NOT_FOUND = "No se ha podido encontrar al jugador."
|
||||
SELF_KICK = "No te puedes expulsar a tí mismo."
|
||||
SELF_BAN = "No te puedes vetar a tí mismo."
|
||||
SELF_MOD = "No te puedes hacerte moderador a tí mismo."
|
||||
KICK_CONFIRM = "¿Seguro que quieres expulsar a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\' para expusar."
|
||||
BAN_CONFIRM = "¿Seguro que quieres vetar a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\' para vetar."
|
||||
PERM_BAN_CONFIRM = "¿Seguro que quieres vetar permanentemente a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\' para vetar."
|
||||
MOD_CONFIRM = "¿Seguro que quieres convertir a '@' en moderador?\Escribe '\\#a0ffa0\\/confirm\\#fff982\\'."
|
||||
PLAYERS_DESC = "/players - Mostrar lista de todos los jugadores y sus IDs"
|
||||
KICK_DESC = "/kick [NAME|ID] - Expulsar al jugador de la partida actual"
|
||||
BAN_DESC = "/ban [NAME|ID] - Vetar al jugador de la partida actual"
|
||||
PERM_BAN_DESC = "/permban [NAME|ID] - Vetar al jugador de todas tus partidas"
|
||||
MOD_DESC = "/moderator [NAME|ID] - Permitir a este jugador usar comandos como /kick, /ban o /permban de cualquier juego que alojes"
|
||||
UNRECOGNIZED = "Comando de chat desconocido."
|
||||
MOD_GRANTED = "\\#fff982\\Ahora eres un Moderador."
|
||||
SELF_BAN = "No te puedes banear a tí mismo."
|
||||
SELF_MOD = "No puedes hacerte moderador a tí mismo."
|
||||
KICK_CONFIRM = "¿Seguro que quieres expulsar a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\' para expulsar."
|
||||
BAN_CONFIRM = "¿Seguro que quieres banear a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\' para banear."
|
||||
PERM_BAN_CONFIRM = "¿Seguro que quieres banear permanentemente a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\' para banear."
|
||||
MOD_CONFIRM = "¿Seguro que quieres hacer moderador a '@'?\nEscribe '\\#a0ffa0\\/confirm\\#fff982\\'."
|
||||
PLAYERS_DESC = "/players - Muestra la lista de todos los jugadores y sus IDs."
|
||||
KICK_DESC = "/kick [NAME|ID] - Expulsa al jugador de la partida actual."
|
||||
BAN_DESC = "/ban [NAME|ID] - Banea al jugador de la partida actual."
|
||||
PERM_BAN_DESC = "/permban [NAME|ID] - Banea al jugador de todas tus partidas."
|
||||
MOD_DESC = "/moderator [NAME|ID] - Permite a un jugador usar comandos como /kick, /ban o /permban de cualquier partida que crees."
|
||||
UNRECOGNIZED = "Comando desconocido."
|
||||
MOD_GRANTED = "\\#fff982\\Ahora eres un moderador."
|
||||
|
||||
[MENU]
|
||||
BACK = "Volver"
|
||||
|
@ -52,37 +52,37 @@ YES = "Sí"
|
|||
|
||||
[CAMERA]
|
||||
CAMERA = "CÁMARA"
|
||||
FREE_CAMERA = "Cámara Libre"
|
||||
ANALOG_CAMERA = "Cámara Analógica"
|
||||
MOUSE_LOOK = "Moviemiento con Ratón"
|
||||
FREE_CAMERA = "Cámara libre"
|
||||
ANALOG_CAMERA = "Cámara analógica"
|
||||
MOUSE_LOOK = "Movimiento con mouse"
|
||||
INVERT_X = "Invertir eje X"
|
||||
INVERT_Y = "Invertir eje Y"
|
||||
X_SENSITIVITY = "Sensibilidad Eje X"
|
||||
Y_SENSITIVITY = "Sensibilidad Eje Y"
|
||||
AGGRESSION = "Agresíon"
|
||||
PAN_LEVEL = "Nivel Seguimiento"
|
||||
X_SENSITIVITY = "Sensibilidad eje X"
|
||||
Y_SENSITIVITY = "Sensibilidad eje Y"
|
||||
AGGRESSION = "Agresión"
|
||||
PAN_LEVEL = "Nivel de seguimiento"
|
||||
DECELERATION = "Deceleración"
|
||||
|
||||
[CHEATS]
|
||||
CHEATS = "TRUCOS"
|
||||
MOON_JUMP = "Salto Lunar"
|
||||
MOON_JUMP = "Salto lunar"
|
||||
GOD_MODE = "Modo Dios"
|
||||
INFINITE_LIVES = "Vidas Ilimitadas"
|
||||
SUPER_SPEED = "Super Velocidad"
|
||||
RESPONSIVE_CONTROLS = "Controles Responsivos"
|
||||
RAPID_FIRE = "Pulsación Rápida (A)"
|
||||
BLJ_ANYWHERE = "BLJ en cualquier parte"
|
||||
ALWAYS_TRIPLE_JUMP = "Siempre hacer Triple Salto"
|
||||
INFINITE_LIVES = "Vidas infinitas"
|
||||
SUPER_SPEED = "Super velocidad"
|
||||
RESPONSIVE_CONTROLS = "Controles responsivos"
|
||||
RAPID_FIRE = "Pulsación rápida (A)"
|
||||
BLJ_ANYWHERE = "BLJ donde sea"
|
||||
ALWAYS_TRIPLE_JUMP = "Siempre hacer triple salto"
|
||||
|
||||
[CONTROLS]
|
||||
CONTROLS = "CONTROLES"
|
||||
|
||||
N64_BINDS = "Asignaciones N64"
|
||||
EXTRA_BINDS = "Asignaciones Extra"
|
||||
N64_BINDS = "Botones N64"
|
||||
EXTRA_BINDS = "Botones Extra"
|
||||
BACKGROUND_GAMEPAD = "Mando en segundo plano"
|
||||
GAMEPAD = "Mando"
|
||||
DEADZONE = "Zona muerta"
|
||||
RUMBLE_STRENGTH = "Fuerza de Vibración"
|
||||
RUMBLE_STRENGTH = "Fuerza de vibración"
|
||||
|
||||
CHAT = "Chat"
|
||||
PLAYERS = "Jugadores"
|
||||
|
@ -111,12 +111,12 @@ C_RIGHT = "C Derecha"
|
|||
[DISPLAY]
|
||||
DISPLAY = "PANTALLA"
|
||||
FULLSCREEN = "Pantalla completa"
|
||||
PRELOAD_TEXTURES = "Precargar Texturas"
|
||||
VSYNC = "Sincronización Vertical"
|
||||
PRELOAD_TEXTURES = "Precargar texturas"
|
||||
VSYNC = "Sincronización vertical"
|
||||
UNCAPPED_FRAMERATE = "FPS sin límite"
|
||||
FRAME_LIMIT = "Límite de FPS"
|
||||
FAST = "Rápido"
|
||||
ACCURATE = "Preciso"
|
||||
FAST = "Rápida"
|
||||
ACCURATE = "Precisa"
|
||||
INTERPOLATION = "Interpolación"
|
||||
NEAREST = "Más cercano"
|
||||
LINEAR = "Lineal"
|
||||
|
@ -128,33 +128,33 @@ D1P5X = "1.5x"
|
|||
D3X = "3x"
|
||||
D10X = "10x"
|
||||
D100X = "100x"
|
||||
DRAW_DISTANCE = "Distancia de Dibujado"
|
||||
DYNOS_PACKS = "Packs DynOS"
|
||||
DRAW_DISTANCE = "Distancia de dibujado"
|
||||
DYNOS_PACKS = "Packs de DynOS"
|
||||
|
||||
[DYNOS]
|
||||
DYNOS = "DYNOS"
|
||||
|
||||
[HOST_MESSAGE]
|
||||
INFO_TITLE = "INFO"
|
||||
WARN_DISCORD = "Invita a amigos haciendo click derecho en su nombre en Discord y seleccionando\n'\\#d0d0ff\\Invitar a unirse\\#c8c8c8\\'.\n\nPuedes invitar en canales de un servidor también presionando el\nbotón \\#d0d0ff\\+\\#c8c8c8\\ al lado del cuadro de texto del chat.\n\nEl estado de Actividad Actual \\#ffa0a0\\debe estar\\#c8c8c8\\ activado en tus \najustes de Discord.\n\nEstár invisible \\#ffa0a0\\te prevendrá\\#c8c8c8\\ de crear invitaciones."
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\Error:\\#c8c8c8\\ No se ha detectado a Discord.\n\n\\#a0a0a0\\Prueba a cerrar el juego,\nreiniciar Discord,\ny abrir el juego de nuevo."
|
||||
WARN_SOCKET = "Las conexiones directas \\#ffa0a0\\requieren\\#c8c8c8\\ que abras los puertos en tu rúter.\n\nAbre el puerto '\\#d0d0ff\\%d\\#c8c8c8\\' con protocolo UDP."
|
||||
HOST = "Alojar"
|
||||
WARN_DISCORD = "Invita a amigos haciendo click derecho en su nombre en Discord y seleccionando\n'\\#d0d0ff\\Invitar a unirse\\#c8c8c8\\'.\n\nPuedes invitar en canales de un servidor también presionando el botón \\#d0d0ff\\+\\#c8c8c8\\ al lado del cuadro de texto del chat.\n\nEl estado de Actividad Actual \\#ffa0a0\\debe estar\\#c8c8c8\\ activado en tus ajustes de Discord.\n\nEstar invisible \\#ffa0a0\\te prevendrá\\#c8c8c8\\ de crear invitaciones."
|
||||
WARN_DISCORD2 = "\\#ffa0a0\\Error:\\#c8c8c8\\ No se ha detectado Discord.\n\n\\#a0a0a0\\Prueba a cerrar el juego,\nreiniciar Discord,\ny abrir el juego de nuevo."
|
||||
WARN_SOCKET = "Las conexiones directas \\#ffa0a0\\requieren\\#c8c8c8\\ que abras los puertos en tu router.\n\nAbre el puerto '\\#d0d0ff\\%d\\#c8c8c8\\' con protocolo UDP."
|
||||
HOST = "Crear"
|
||||
|
||||
[HOST_MODS]
|
||||
ROMHACKS = "ROMHACKS"
|
||||
MODS = "MODS"
|
||||
|
||||
[HOST_SAVE]
|
||||
SAVE_TITLE = "GUARDAR"
|
||||
SAVE_TITLE = "RANURAS DE\nGUARDADO"
|
||||
ERASE_TITLE = "BORRAR"
|
||||
CONFIRM = "¿Seguro que quieres borrar esta partida?"
|
||||
ERASE = "Borrar"
|
||||
|
||||
[HOST_SETTINGS]
|
||||
SETTINGS = "AJUSTES"
|
||||
NONSOLID = "Intangible"
|
||||
SOLID = "Tangible"
|
||||
NONSOLID = "No Sólida"
|
||||
SOLID = "Sólida"
|
||||
FRIENDLY_FIRE = "Fuego Amigo"
|
||||
PLAYER_INTERACTION = "Interacción entre jugadores"
|
||||
WEAK = "Poca"
|
||||
|
@ -163,7 +163,7 @@ TOO_MUCH = "Demasiada"
|
|||
KNOCKBACK_STRENGTH = "Fuerza de retroceso"
|
||||
LEAVE_LEVEL = "Salir del nivel"
|
||||
STAY_IN_LEVEL = "Seguir en el nivel"
|
||||
NONSTOP = "Siguiente misión"
|
||||
NONSTOP = "Sin parar"
|
||||
ON_STAR_COLLECTION = "Al conseguir una estrella"
|
||||
SKIP_INTRO_CUTSCENE = "Saltar cinemática de introducción"
|
||||
SHARE_LIVES = "Compartir vidas"
|
||||
|
@ -172,33 +172,33 @@ BUBBLE_ON_DEATH = "Burbuja al morir"
|
|||
AMOUNT_OF_PLAYERS = "Número de jugadores"
|
||||
|
||||
[HOST]
|
||||
SERVER_TITLE = "SERVIDOR"
|
||||
HOST_TITLE = "ALOJAR"
|
||||
SERVER_TITLE = "PARTIDA"
|
||||
HOST_TITLE = "CREAR"
|
||||
DISCORD = "Discord"
|
||||
COOPNET = "CoopNet"
|
||||
DIRECT_CONNECTION = "Conexión Directa"
|
||||
NETWORK_SYSTEM = "Modo de conexión"
|
||||
PORT = "Puerto"
|
||||
SAVE_SLOT = "Ranura de Guardado"
|
||||
SAVE_SLOT = "Ranuras"
|
||||
SETTINGS = "Ajustes"
|
||||
MODS = "Mods"
|
||||
ROMHACKS = "Rom-Hacks"
|
||||
APPLY = "Aplicar"
|
||||
HOST = "Alojar"
|
||||
HOST = "Crear"
|
||||
|
||||
[JOIN_MESSAGE]
|
||||
JOINING = "UNIENDOSE"
|
||||
JOINING = "UNIÉNDOSE"
|
||||
|
||||
[JOIN]
|
||||
JOIN_TITLE = "UNIRSE"
|
||||
JOIN_DISCORD = "Para unirte a un lobby en \\#d0d0ff\\Discord\\#c8c8c8\\:\n\nManten el juego abierto y acepta la invitación.\n\nSi la invitación dice que la partida ha terminado, haz click en el nombre de la persona que te invitó para refrescarla."
|
||||
JOIN_SOCKET = "Introduce la IP y el puerto de \\#d0d0ff\\conexión directa\\#c8c8c8\\:"
|
||||
JOIN_DISCORD = "Para unirte a un lobby en \\#d0d0ff\\Discord\\#c8c8c8\\:\n\nMantén el juego abierto y acepta la invitación.\n\nSi la invitación dice que la partida ha terminado, haz click en el nombre de la persona que te invitó para\nrefrescarla."
|
||||
JOIN_SOCKET = "Introduce la IP y el puerto de la \\#d0d0ff\\conexión directa\\#c8c8c8\\:"
|
||||
JOIN = "Unirse"
|
||||
|
||||
[MAIN]
|
||||
QUIT_TITLE = "SALIR"
|
||||
QUIT_CONFIRM = "¿Seguro que quieres salir?"
|
||||
HOST = "Alojar"
|
||||
HOST = "Crear"
|
||||
JOIN = "Unirse"
|
||||
OPTIONS = "Opciones"
|
||||
QUIT = "Salir"
|
||||
|
@ -206,9 +206,9 @@ QUIT = "Salir"
|
|||
[MENU_OPTIONS]
|
||||
MAIN_MENU = "MENÚ PRINCIPAL"
|
||||
LEVEL = "Nivel"
|
||||
USE_STAGE_MUSIC = "Usar Música del Nivel"
|
||||
RANDOM_STAGE = "Nivel Aleatório"
|
||||
PLAY_VANILLA_DEMOS = "Reproducir Demostraciones Vanilla"
|
||||
USE_STAGE_MUSIC = "Usar música del nivel"
|
||||
RANDOM_STAGE = "Nivel aleatorio"
|
||||
PLAY_VANILLA_DEMOS = "Demos originales"
|
||||
|
||||
[MISC]
|
||||
DEBUG_TITLE = "DEPURACIÓN"
|
||||
|
@ -217,10 +217,10 @@ LUA_PROFILER = "Perfilador de Lua"
|
|||
DEBUG_PRINT = "Mensajes de Depuración"
|
||||
DEBUG_INFO = "Información de Depuración"
|
||||
DEBUG_ERRORS = "Errores de Depuración"
|
||||
MISC_TITLE = "MISCELÁNEO"
|
||||
PAUSE_IN_SINGLEPLAYER = "Pausa en Modo de Un jugador"
|
||||
DISABLE_POPUPS = "Deshabilitar Mensajes Emergentes"
|
||||
MENU_OPTIONS = "Opciones del Menú"
|
||||
MISC_TITLE = "OTROS"
|
||||
PAUSE_IN_SINGLEPLAYER = "Pausa en modo de un jugador"
|
||||
DISABLE_POPUPS = "Deshabilitar mensajes emergentes"
|
||||
MENU_OPTIONS = "Opciones del menú"
|
||||
DEBUG = "Depuración"
|
||||
LANGUAGE = "Idioma"
|
||||
|
||||
|
@ -234,26 +234,26 @@ CAMERA = "Cámara"
|
|||
CONTROLS = "Controles"
|
||||
DISPLAY = "Pantalla"
|
||||
SOUND = "Sonido"
|
||||
MISC = "Misceláneo"
|
||||
MISC = "Otros"
|
||||
|
||||
[PAUSE]
|
||||
QUIT_TITLE = "SALIR"
|
||||
QUIT_HOST = "¿Seguro que quieres dejar de alojar?"
|
||||
QUIT_HOST = "¿Seguro que quieres finalizar la partida?"
|
||||
QUIT_CLIENT = "¿Seguro que te quieres desconectar?"
|
||||
PAUSE_TITLE = "PAUSA"
|
||||
PLAYER = "Jugador"
|
||||
DYNOS_PACKS = "Packs DynOS"
|
||||
DYNOS_PACKS = "Packs de DynOS"
|
||||
OPTIONS = "Opciones"
|
||||
CHEATS = "Trucos"
|
||||
SERVER_SETTINGS = "Ajustes del Servidor"
|
||||
SERVER_SETTINGS = "Ajustes de la partida"
|
||||
RESUME = "Continuar"
|
||||
STOP_HOSTING = "Dejar de Alojar"
|
||||
STOP_HOSTING = "Finalizar partida"
|
||||
DISCONNECT = "Desconectarse"
|
||||
|
||||
[PLAYER]
|
||||
PLAYER_TITLE = "JUGADOR"
|
||||
OVERALLS = "Tirantes"
|
||||
SHIRT = "Camisa"
|
||||
OVERALLS = "Overoles"
|
||||
SHIRT = "Camiseta"
|
||||
GLOVES = "Guantes"
|
||||
SHOES = "Zapatos"
|
||||
HAIR = "Pelo"
|
||||
|
@ -268,7 +268,7 @@ BLUE = "Azul"
|
|||
PLAYER = "Jugador"
|
||||
NAME = "Nombre"
|
||||
MODEL = "Modelo"
|
||||
PALETTE_PRESET = "Perfil de Paleta"
|
||||
PALETTE_PRESET = "Paletas predeterminadas"
|
||||
EDIT_PALETTE = "Editar Paleta"
|
||||
|
||||
[PALETTE]
|
||||
|
@ -304,20 +304,20 @@ RASPBERRY = "Frambuesa"
|
|||
BUBBLEGUM = "Chicle"
|
||||
ICE_MARIO = "Mario de Hielo"
|
||||
ICE_LUIGI = "Luigi de Hielo"
|
||||
CUSTOM = "Personalizado"
|
||||
CUSTOM = "Personalizada"
|
||||
|
||||
[PLAYER_LIST]
|
||||
PLAYERS = "JUGADORES"
|
||||
NAME = "nombre"
|
||||
LOCATION = "localización"
|
||||
ACT = "recorrido"
|
||||
ACT = "acto"
|
||||
|
||||
[SOUND]
|
||||
SOUND = "SONIDO"
|
||||
MASTER_VOLUME = "Volumen Maestro"
|
||||
MUSIC_VOLUME = "Volumen Música"
|
||||
SFX_VOLUME = "Volumen Efectos de Sonido"
|
||||
ENV_VOLUME = "Volumen Entorno"
|
||||
MASTER_VOLUME = "Volumen General"
|
||||
MUSIC_VOLUME = "Volumen de Música"
|
||||
SFX_VOLUME = "Volumen de Efectos de Sonido"
|
||||
ENV_VOLUME = "Volumen de Entorno"
|
||||
|
||||
[LANGUAGE]
|
||||
LANGUAGE = "IDIOMA"
|
|
@ -28,6 +28,14 @@ for i = 0, (MAX_PLAYERS - 1) do
|
|||
s.rank = 0
|
||||
end
|
||||
|
||||
local sKnockbackActions = {
|
||||
ACT_SOFT_FORWARD_GROUND_KB, ACT_FORWARD_GROUND_KB, ACT_HARD_FORWARD_GROUND_KB,
|
||||
ACT_FORWARD_AIR_KB, ACT_FORWARD_AIR_KB, ACT_HARD_FORWARD_AIR_KB,
|
||||
ACT_FORWARD_WATER_KB, ACT_FORWARD_WATER_KB, ACT_FORWARD_WATER_KB,
|
||||
ACT_SOFT_BACKWARD_GROUND_KB, ACT_BACKWARD_GROUND_KB, ACT_HARD_BACKWARD_GROUND_KB,
|
||||
ACT_BACKWARD_AIR_KB, ACT_BACKWARD_AIR_KB, ACT_HARD_BACKWARD_AIR_KB,
|
||||
ACT_BACKWARD_WATER_KB, ACT_BACKWARD_WATER_KB, ACT_BACKWARD_WATER_KB
|
||||
}
|
||||
------------
|
||||
-- hammer --
|
||||
------------
|
||||
|
@ -361,6 +369,27 @@ function mario_update(m)
|
|||
local s = gPlayerSyncTable[m.playerIndex]
|
||||
local np = gNetworkPlayers[m.playerIndex]
|
||||
|
||||
-- increase knockback animations
|
||||
local animInfo = nil
|
||||
if m.marioObj ~= nil then
|
||||
animInfo = m.marioObj.header.gfx.animInfo
|
||||
end
|
||||
for i, value in ipairs(sKnockbackActions) do
|
||||
if m.action == value then
|
||||
local frame = animInfo.animFrame
|
||||
local loopEnd = frame
|
||||
if animInfo.curAnim ~= nil then
|
||||
loopEnd = animInfo.curAnim.loopEnd
|
||||
end
|
||||
|
||||
if frame < loopEnd - 2 then
|
||||
frame = frame + 1
|
||||
end
|
||||
|
||||
animInfo.animFrame = frame
|
||||
end
|
||||
end
|
||||
|
||||
-- clear invincibilities
|
||||
m.invincTimer = 0
|
||||
if m.knockbackTimer > 5 then
|
||||
|
|
|
@ -1163,7 +1163,7 @@ function act_walking(m)
|
|||
end
|
||||
|
||||
function act_hold_walking(m)
|
||||
if m.heldObj.behavior == bhvJumpingBox then
|
||||
if m.heldObj ~= nil and m.heldObj.behavior == bhvJumpingBox then
|
||||
return set_mario_action(m, ACT_CRAZY_BOX_BOUNCE, 0)
|
||||
end
|
||||
|
||||
|
|
|
@ -2195,27 +2195,46 @@ possibility.\
|
|||
Good luck and\
|
||||
frustration resistance.")
|
||||
|
||||
-- smlua_text_utils_dialog_replace(DIALOG_063,1,5,30,200, "It's really a shame but\
|
||||
-- this level was way too\
|
||||
-- big for the level importer\
|
||||
-- so I had to split it\
|
||||
-- into two parts.\
|
||||
-- That means I CAN'T place\
|
||||
-- red coins in the whole\
|
||||
-- level. Sad, isn't it?\
|
||||
-- I know that you would\
|
||||
-- enjoy collecting 30\
|
||||
-- red coins, right?\
|
||||
-- Well then, instead,\
|
||||
-- the red coins are all\
|
||||
-- beyond the cannon.\
|
||||
-- And since they are so\
|
||||
-- close together\
|
||||
-- I won't tell you how\
|
||||
-- many there are.\
|
||||
-- \
|
||||
-- (Well, honestly, I forgot\
|
||||
-- how many I placed.)")
|
||||
|
||||
smlua_text_utils_dialog_replace(DIALOG_063,1,5,30,200, "It's really a shame but\
|
||||
this level was way too\
|
||||
big for the level importer\
|
||||
so I had to split it\
|
||||
into two parts.\
|
||||
That means I CAN'T place\
|
||||
Nah! Just kidding!\
|
||||
You're no longer playing\
|
||||
a Nintendo 64 rom-hack.\
|
||||
It's the pc port we're\
|
||||
talking about!\
|
||||
That means I CAN place\
|
||||
red coins in the whole\
|
||||
level. Sad, isn't it?\
|
||||
level. Great, isn't it?\
|
||||
I know that you would\
|
||||
enjoy collecting 30\
|
||||
red coins, right?\
|
||||
Well then, instead,\
|
||||
the red coins are all\
|
||||
beyond the cannon.\
|
||||
And since they are so\
|
||||
close together\
|
||||
I won't tell you how\
|
||||
many there are.\
|
||||
\
|
||||
(Well, honestly, I forgot\
|
||||
how many I placed.)")
|
||||
red coins. So, after 9\
|
||||
years, it's finally\
|
||||
possible. Have fun!")
|
||||
|
||||
smlua_text_utils_dialog_replace(DIALOG_064,1,5,30,200, "You should already know\
|
||||
the concept of this\
|
||||
|
|
|
@ -161,6 +161,8 @@ u32 get_mario_spawn_type(struct Object *o) {
|
|||
}
|
||||
|
||||
struct ObjectWarpNode *area_get_warp_node(u8 id) {
|
||||
if (!gCurrentArea || !gCurrentArea->warpNodes) { return NULL; }
|
||||
|
||||
struct ObjectWarpNode *node = NULL;
|
||||
|
||||
for (node = gCurrentArea->warpNodes; node != NULL; node = node->next) {
|
||||
|
|
|
@ -170,5 +170,5 @@ static void (*sBetaBooKeyActions[])(void) = { beta_boo_key_inside_boo_loop, beta
|
|||
* Update function for bhvBetaBooKey.
|
||||
*/
|
||||
void bhv_beta_boo_key_loop(void) {
|
||||
cur_obj_call_action_function(sBetaBooKeyActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sBetaBooKeyActions);
|
||||
}
|
||||
|
|
|
@ -555,7 +555,7 @@ void bhv_boo_loop(void) {
|
|||
//PARTIAL_UPDATE
|
||||
|
||||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_call_action_function(sBooActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sBooActions);
|
||||
cur_obj_move_standard(78);
|
||||
boo_approach_target_opacity_and_update_scale();
|
||||
|
||||
|
@ -793,7 +793,7 @@ void bhv_big_boo_loop(void) {
|
|||
o->oGraphYOffset = o->oBooBaseScale * 60.0f;
|
||||
|
||||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_call_action_function(sBooGivingStarActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sBooGivingStarActions);
|
||||
cur_obj_move_standard(78);
|
||||
|
||||
boo_approach_target_opacity_and_update_scale();
|
||||
|
@ -870,7 +870,7 @@ void bhv_boo_with_cage_loop(void) {
|
|||
//PARTIAL_UPDATE
|
||||
|
||||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_call_action_function(sBooWithCageActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sBooWithCageActions);
|
||||
cur_obj_move_standard(78);
|
||||
|
||||
boo_approach_target_opacity_and_update_scale();
|
||||
|
|
|
@ -59,7 +59,7 @@ void bhv_bowser_tail_anchor_init(void) {
|
|||
}
|
||||
|
||||
void bhv_bowser_tail_anchor_loop(void) {
|
||||
cur_obj_call_action_function(sBowserTailAnchorActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sBowserTailAnchorActions);
|
||||
o->oParentRelativePosX = 90.0f;
|
||||
if (o->parentObj->oAction == 4)
|
||||
o->parentObj->oIntangibleTimer = -1;
|
||||
|
@ -1204,7 +1204,7 @@ void bowser_free_update(void) {
|
|||
o->oBowserUnk10E = 0;
|
||||
|
||||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_call_action_function(sBowserActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sBowserActions);
|
||||
cur_obj_move_standard(-78);
|
||||
if (bowser_check_fallen_off_stage())
|
||||
o->oAction = 2; // bowser go home?
|
||||
|
@ -1657,7 +1657,7 @@ void bhv_falling_bowser_platform_loop(void) {
|
|||
}
|
||||
}
|
||||
|
||||
cur_obj_call_action_function(sFallingBowserPlatformActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sFallingBowserPlatformActions);
|
||||
}
|
||||
|
||||
void bowser_flame_despawn(void) {
|
||||
|
|
|
@ -275,7 +275,7 @@ void (*sBowserPuzzlePieceActions[])(void) = {
|
|||
void bhv_lll_bowser_puzzle_piece_loop(void) {
|
||||
bhv_lll_bowser_puzzle_piece_update();
|
||||
|
||||
cur_obj_call_action_function(sBowserPuzzlePieceActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sBowserPuzzlePieceActions);
|
||||
|
||||
o->oPosX = o->oBowserPuzzlePieceOffsetX + o->oHomeX;
|
||||
o->oPosY = o->oBowserPuzzlePieceOffsetY + o->oHomeY;
|
||||
|
|
|
@ -28,7 +28,7 @@ void (*sBirdChirpChirpActions[])(void) = { bub_spawner_act_0, bub_spawner_act_1,
|
|||
bub_spawner_act_2, bub_spawner_act_3 };
|
||||
|
||||
void bhv_bub_spawner_loop(void) {
|
||||
cur_obj_call_action_function(sBirdChirpChirpActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sBirdChirpChirpActions);
|
||||
}
|
||||
|
||||
void bub_move_vertically(s32 a0) {
|
||||
|
@ -136,7 +136,7 @@ void bhv_bub_loop(void) {
|
|||
}
|
||||
o->oWallHitboxRadius = 30.0f;
|
||||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_call_action_function(sCheepCheepActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sCheepCheepActions);
|
||||
cur_obj_move_using_fvel_and_gravity();
|
||||
if (o->parentObj->oAction == 2)
|
||||
obj_mark_for_deletion(o);
|
||||
|
|
|
@ -86,7 +86,7 @@ void (*sBulletBillActions[])(void) = { bullet_bill_act_0, bullet_bill_act_1, bul
|
|||
bullet_bill_act_3, bullet_bill_act_4 };
|
||||
|
||||
void bhv_bullet_bill_loop(void) {
|
||||
cur_obj_call_action_function(sBulletBillActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sBulletBillActions);
|
||||
if (cur_obj_check_interacted())
|
||||
o->oAction = 4;
|
||||
}
|
||||
|
|
|
@ -237,7 +237,7 @@ void bhv_cannon_base_loop(void) {
|
|||
cur_obj_push_mario_away_from_cylinder(220, 300);
|
||||
}
|
||||
|
||||
cur_obj_call_action_function(sOpenedCannonActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sOpenedCannonActions);
|
||||
if (o->oCannonUnkF8)
|
||||
o->oCannonUnkF8++;
|
||||
o->oInteractStatus = 0;
|
||||
|
|
|
@ -65,5 +65,5 @@ void bhv_cap_switch_loop(void) {
|
|||
sync_object_init_field(o, &capSwitchForcePress);
|
||||
}
|
||||
|
||||
cur_obj_call_action_function(sCapSwitchActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sCapSwitchActions);
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ void (*sChuckyaActions[])(void) = { chuckya_act_0, chuckya_act_1, chuckya_act_2,
|
|||
|
||||
void chuckya_move(void) {
|
||||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_call_action_function(sChuckyaActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sChuckyaActions);
|
||||
cur_obj_move_standard(-30);
|
||||
if (o->oInteractStatus & INT_STATUS_GRABBED_MARIO) {
|
||||
o->oAction = 1;
|
||||
|
|
|
@ -255,7 +255,7 @@ void coin_inside_boo_act_0(void) {
|
|||
void (*sCoinInsideBooActions[])(void) = { coin_inside_boo_act_0, coin_inside_boo_act_1 };
|
||||
|
||||
void bhv_coin_inside_boo_loop(void) {
|
||||
cur_obj_call_action_function(sCoinInsideBooActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sCoinInsideBooActions);
|
||||
}
|
||||
|
||||
void bhv_coin_sparkles_loop(void) {
|
||||
|
|
|
@ -154,7 +154,7 @@ struct SpawnParticlesInfo D_8032F3FC = { 0, 5, MODEL_WHITE_PARTICLE_DL, 0,
|
|||
2.0f, 2.0f };
|
||||
|
||||
void bhv_elevator_loop(void) {
|
||||
cur_obj_call_action_function(sElevatorActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sElevatorActions);
|
||||
|
||||
// allow bubbled players to pass through
|
||||
if (gMarioStates[0].action == ACT_BUBBLED) {
|
||||
|
|
|
@ -214,5 +214,5 @@ void bhv_exclamation_box_init(void) {
|
|||
|
||||
void bhv_exclamation_box_loop(void) {
|
||||
cur_obj_scale(2.0f);
|
||||
cur_obj_call_action_function(sExclamationBoxActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sExclamationBoxActions);
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ static void (*sFishSpawnerActions[])(void) = {
|
|||
};
|
||||
|
||||
void bhv_fish_spawner_loop(void) {
|
||||
cur_obj_call_action_function(sFishSpawnerActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sFishSpawnerActions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -276,7 +276,7 @@ void bhv_fish_loop(void)
|
|||
}
|
||||
|
||||
// Call fish action methods and apply physics engine.
|
||||
cur_obj_call_action_function(sFishActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sFishActions);
|
||||
cur_obj_move_using_fvel_and_gravity();
|
||||
|
||||
// If the parent object has action set to two, then delete the fish object.
|
||||
|
|
|
@ -99,7 +99,7 @@ void (*sHeaveHoActions[])(void) = { heave_ho_act_0, heave_ho_act_1, heave_ho_act
|
|||
|
||||
void heave_ho_move(void) {
|
||||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_call_action_function(sHeaveHoActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sHeaveHoActions);
|
||||
cur_obj_move_standard(-78);
|
||||
if (o->oMoveFlags & OBJ_MOVE_MASK_IN_WATER)
|
||||
o->oGraphYOffset = -15.0f;
|
||||
|
|
|
@ -41,7 +41,7 @@ void jumping_box_free_update(void) {
|
|||
obj_set_hitbox(o, &sJumpingBoxHitbox);
|
||||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_move_standard(78);
|
||||
cur_obj_call_action_function(sJumpingBoxActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sJumpingBoxActions);
|
||||
}
|
||||
|
||||
void bhv_jumping_box_loop(void) {
|
||||
|
|
|
@ -365,7 +365,7 @@ void king_bobomb_move(void) {
|
|||
cur_obj_move_standard(-78);
|
||||
else
|
||||
cur_obj_move_using_fvel_and_gravity();
|
||||
cur_obj_call_action_function(sKingBobombActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sKingBobombActions);
|
||||
exec_anim_sound_state(sKingBobombSoundStates);
|
||||
s32 distanceToPlayer = dist_between_objects(o, gMarioStates[0].marioObj);
|
||||
if (distanceToPlayer < 5000.0f * draw_distance_scalar())
|
||||
|
|
|
@ -60,7 +60,7 @@ void bhv_lll_rotating_block_fire_bars_loop(void) {
|
|||
sync_object_init(o, 4000.0f);
|
||||
sync_object_init_field(o, &o->oAngleVelYaw);
|
||||
}
|
||||
cur_obj_call_action_function(sRotatingCwFireBarsActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sRotatingCwFireBarsActions);
|
||||
if (o->oBehParams2ndByte == 0)
|
||||
load_object_collision_model();
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ void mr_i_piranha_particle_act_1(void) {
|
|||
void (*sMrIParticleActions[])(void) = { mr_i_piranha_particle_act_0, mr_i_piranha_particle_act_1 };
|
||||
|
||||
void bhv_mr_i_particle_loop(void) {
|
||||
cur_obj_call_action_function(sMrIParticleActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sMrIParticleActions);
|
||||
}
|
||||
|
||||
void spawn_mr_i_particle(void) {
|
||||
|
@ -283,7 +283,7 @@ void bhv_mr_i_loop(void) {
|
|||
s32 distanceToPlayer = player ? dist_between_objects(o, player) : 10000;
|
||||
|
||||
obj_set_hitbox(o, &sMrIHitbox);
|
||||
cur_obj_call_action_function(sMrIActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sMrIActions);
|
||||
if (o->oAction != 3) {
|
||||
if (distanceToPlayer > 3000.0f || o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM) {
|
||||
o->oAction = 0;
|
||||
|
|
|
@ -369,7 +369,7 @@ void bhv_piranha_plant_loop(void) {
|
|||
cur_obj_set_hitbox_radius_and_height(150.0f, 100.0f);
|
||||
cur_obj_set_hurtbox_radius_and_height(150.0f, 100.0f);
|
||||
|
||||
cur_obj_call_action_function(TablePiranhaPlantActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(TablePiranhaPlantActions);
|
||||
// In WF, hide all Piranha Plants once high enough up.
|
||||
if (gCurrLevelNum == LEVEL_WF) {
|
||||
struct Object* player = gMarioStates[0].marioObj;
|
||||
|
|
|
@ -63,5 +63,5 @@ void bhv_grindel_thwomp_loop(void) {
|
|||
sync_object_init_field(o, &o->oTimer);
|
||||
sync_object_init_field(o, &o->oVelY);
|
||||
}
|
||||
cur_obj_call_action_function(sGrindelThwompActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sGrindelThwompActions);
|
||||
}
|
||||
|
|
|
@ -85,6 +85,6 @@ void bhv_tox_box_loop(void) {
|
|||
sync_object_init_field(o, &o->oToxBoxMovementStep);
|
||||
}
|
||||
}
|
||||
cur_obj_call_action_function(sToxBoxActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sToxBoxActions);
|
||||
load_object_collision_model();
|
||||
}
|
||||
|
|
|
@ -164,5 +164,5 @@ void bhv_tumbling_bridge_loop(void) {
|
|||
}
|
||||
}
|
||||
|
||||
cur_obj_call_action_function(sTumblingBridgeActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sTumblingBridgeActions);
|
||||
}
|
||||
|
|
|
@ -160,7 +160,7 @@ void bhv_tuxies_mother_loop(void) {
|
|||
}
|
||||
o->activeFlags |= ACTIVE_FLAG_UNK10;
|
||||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_call_action_function(sTuxiesMotherActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sTuxiesMotherActions);
|
||||
cur_obj_move_standard(-78);
|
||||
play_penguin_walking_sound(PENGUIN_WALK_BIG);
|
||||
o->oInteractStatus = 0;
|
||||
|
@ -289,7 +289,7 @@ void small_penguin_free_actions(void) {
|
|||
cur_obj_become_tangible();
|
||||
cur_obj_enable_rendering();
|
||||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_call_action_function(sSmallPenguinActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sSmallPenguinActions);
|
||||
cur_obj_move_standard(-78);
|
||||
play_penguin_walking_sound(PENGUIN_WALK_BABY);
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ void bhv_tweester_loop(void) {
|
|||
}
|
||||
|
||||
obj_set_hitbox(o, &sTweesterHitbox);
|
||||
cur_obj_call_action_function(sTweesterActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sTweesterActions);
|
||||
o->oInteractStatus = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -504,7 +504,7 @@ void ukiki_free_loop(void) {
|
|||
s32 steepSlopeAngleDegrees;
|
||||
|
||||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_call_action_function(sUkikiActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sUkikiActions);
|
||||
|
||||
if (o->oAction == UKIKI_ACT_GO_TO_CAGE || o->oAction == UKIKI_ACT_RETURN_HOME) {
|
||||
steepSlopeAngleDegrees = -88;
|
||||
|
|
|
@ -103,5 +103,5 @@ void (*sUkikiCageActions[])(void) = {
|
|||
* Main behavior loop for the cage. Only calls the relevant action.
|
||||
*/
|
||||
void bhv_ukiki_cage_loop(void) {
|
||||
cur_obj_call_action_function(sUkikiCageActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sUkikiCageActions);
|
||||
}
|
||||
|
|
|
@ -284,7 +284,7 @@ void bhv_whomp_loop(void) {
|
|||
}
|
||||
|
||||
cur_obj_update_floor_and_walls();
|
||||
cur_obj_call_action_function(sWhompActions);
|
||||
CUR_OBJ_CALL_ACTION_FUNCTION(sWhompActions);
|
||||
cur_obj_move_standard(-20);
|
||||
if (o->oAction != 9) {
|
||||
// o->oBehParams2ndByte here seems to be a flag
|
||||
|
|
|
@ -3297,11 +3297,6 @@ void soft_reset_camera(struct Camera* c) {
|
|||
* Reset all the camera variables to their arcane defaults
|
||||
*/
|
||||
void reset_camera(struct Camera *c) {
|
||||
UNUSED s32 unused = 0;
|
||||
UNUSED u8 unused1[16];
|
||||
UNUSED struct LinearTransitionPoint *start = &sModeInfo.transitionStart;
|
||||
UNUSED struct LinearTransitionPoint *end = &sModeInfo.transitionEnd;
|
||||
|
||||
gCamera = c;
|
||||
gCameraMovementFlags = 0;
|
||||
s2ndRotateFlags = 0;
|
||||
|
@ -3315,7 +3310,6 @@ void reset_camera(struct Camera *c) {
|
|||
unused8032CFCC = 0;
|
||||
gSecondCameraFocus = NULL;
|
||||
sCButtonsPressed = 0;
|
||||
vec3f_copy(sModeTransition.marioPos, sMarioCamState->pos);
|
||||
sModeTransition.framesLeft = 0;
|
||||
unused8032CFCC = -1;
|
||||
unused8032CFC8 = -1;
|
||||
|
@ -3340,11 +3334,19 @@ void reset_camera(struct Camera *c) {
|
|||
sCSideButtonYaw = 0;
|
||||
s8DirModeBaseYaw = 0;
|
||||
s8DirModeYawOffset = 0;
|
||||
|
||||
if (c) {
|
||||
c->doorStatus = DOOR_DEFAULT;
|
||||
}
|
||||
|
||||
if (sMarioCamState) {
|
||||
vec3f_copy(sModeTransition.marioPos, sMarioCamState->pos);
|
||||
sMarioCamState->headRotation[0] = 0;
|
||||
sMarioCamState->headRotation[1] = 0;
|
||||
sMarioCamState->cameraEvent = 0;
|
||||
sMarioCamState->usedObj = NULL;
|
||||
}
|
||||
|
||||
gLakituState.shakeMagnitude[0] = 0;
|
||||
gLakituState.shakeMagnitude[1] = 0;
|
||||
gLakituState.shakeMagnitude[2] = 0;
|
||||
|
@ -3355,12 +3357,14 @@ void reset_camera(struct Camera *c) {
|
|||
gLakituState.unusedVec1[1] = 0.f;
|
||||
gLakituState.unusedVec1[2] = 0.f;
|
||||
gLakituState.lastFrameAction = 0;
|
||||
|
||||
set_fov_function(CAM_FOV_DEFAULT);
|
||||
sFOVState.fov = 45.f;
|
||||
sFOVState.fovOffset = 0.f;
|
||||
sFOVState.unusedIsSleeping = 0;
|
||||
sFOVState.shakeAmplitude = 0.f;
|
||||
sFOVState.shakePhase = 0;
|
||||
|
||||
sObjectCutscene = 0;
|
||||
gRecentCutscene = 0;
|
||||
unused8033B30C = 0;
|
||||
|
|
|
@ -59,7 +59,7 @@ enum InteractionFlag {
|
|||
(INT_SLIDE_KICK | INT_FAST_ATTACK_OR_SHELL)
|
||||
|
||||
u8 sDelayInvincTimer;
|
||||
s16 sInvulnerable;
|
||||
s16 gInteractionInvulnerable;
|
||||
u32 interact_coin(struct MarioState *, u32, struct Object *);
|
||||
u32 interact_water_ring(struct MarioState *, u32, struct Object *);
|
||||
u32 interact_star_or_key(struct MarioState *, u32, struct Object *);
|
||||
|
@ -824,7 +824,7 @@ u32 take_damage_from_interact_object(struct MarioState *m) {
|
|||
u32 take_damage_and_knock_back(struct MarioState *m, struct Object *o) {
|
||||
u32 damage;
|
||||
|
||||
if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)
|
||||
if (!gInteractionInvulnerable && !(m->flags & MARIO_VANISH_CAP)
|
||||
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
||||
o->oInteractStatus = INT_STATUS_INTERACTED | INT_STATUS_ATTACKED_MARIO;
|
||||
m->interactObj = o;
|
||||
|
@ -1309,7 +1309,7 @@ static u8 resolve_player_collision(struct MarioState* m, struct MarioState* m2)
|
|||
velY = fmax(fmin(55.0f, 15.0f + fabs(m->vel[1])), 35.0f);
|
||||
} else if (m->action == ACT_DOUBLE_JUMP) {
|
||||
mario_stop_riding_and_holding(m);
|
||||
set_mario_action(m, (m->specialTripleJump && m->playerIndex == 0) ? ACT_SPECIAL_TRIPLE_JUMP : ACT_TRIPLE_JUMP, 0);
|
||||
set_mario_action(m, (m->specialTripleJump && m->playerIndex == 0) ? ACT_SPECIAL_TRIPLE_JUMP : m->flags & MARIO_WING_CAP ? ACT_FLYING_TRIPLE_JUMP : ACT_TRIPLE_JUMP, 0);
|
||||
velY = fmax(fmin(60.0f, 20.0f + fabs(m->vel[1])), 40.0f);
|
||||
} else {
|
||||
mario_stop_riding_and_holding(m);
|
||||
|
@ -1353,6 +1353,8 @@ u8 player_is_sliding(struct MarioState* m) {
|
|||
}
|
||||
|
||||
u8 passes_pvp_interaction_checks(struct MarioState* attacker, struct MarioState* victim) {
|
||||
if (!attacker || !victim) { return false; }
|
||||
|
||||
// attacked
|
||||
u8 isInCutscene = ((attacker->action & ACT_GROUP_MASK) == ACT_GROUP_CUTSCENE) || ((victim->action & ACT_GROUP_MASK) == ACT_GROUP_CUTSCENE);
|
||||
isInCutscene = isInCutscene || (attacker->action == ACT_IN_CANNON) || (victim->action == ACT_IN_CANNON);
|
||||
|
@ -1587,7 +1589,7 @@ u32 interact_strong_wind(struct MarioState *m, UNUSED u32 interactType, struct O
|
|||
u32 interact_flame(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
|
||||
u32 burningAction = ACT_BURNING_JUMP;
|
||||
|
||||
if (!sInvulnerable && !(m->flags & MARIO_METAL_CAP) && !(m->flags & MARIO_VANISH_CAP)
|
||||
if (!gInteractionInvulnerable && !(m->flags & MARIO_METAL_CAP) && !(m->flags & MARIO_VANISH_CAP)
|
||||
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
||||
queue_rumble_data_mario(m, 5, 80);
|
||||
|
||||
|
@ -1614,7 +1616,7 @@ u32 interact_flame(struct MarioState *m, UNUSED u32 interactType, struct Object
|
|||
}
|
||||
|
||||
u32 interact_snufit_bullet(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
|
||||
if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)) {
|
||||
if (!gInteractionInvulnerable && !(m->flags & MARIO_VANISH_CAP)) {
|
||||
if (m->flags & MARIO_METAL_CAP) {
|
||||
o->oInteractStatus = INT_STATUS_INTERACTED | INT_STATUS_WAS_ATTACKED;
|
||||
play_sound(SOUND_ACTION_UNKNOWN458, m->marioObj->header.gfx.cameraToObject);
|
||||
|
@ -1679,7 +1681,7 @@ u32 interact_bully(struct MarioState *m, UNUSED u32 interactType, struct Object
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
else if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)
|
||||
else if (!gInteractionInvulnerable && !(m->flags & MARIO_VANISH_CAP)
|
||||
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
||||
o->oInteractStatus = INT_STATUS_INTERACTED;
|
||||
m->invincTimer = 2;
|
||||
|
@ -1699,7 +1701,7 @@ u32 interact_bully(struct MarioState *m, UNUSED u32 interactType, struct Object
|
|||
}
|
||||
|
||||
u32 interact_shock(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
|
||||
if (!sInvulnerable && !(m->flags & MARIO_VANISH_CAP)
|
||||
if (!gInteractionInvulnerable && !(m->flags & MARIO_VANISH_CAP)
|
||||
&& !(o->oInteractionSubtype & INT_SUBTYPE_DELAY_INVINCIBILITY)) {
|
||||
u32 actionArg = (m->action & (ACT_FLAG_AIR | ACT_FLAG_ON_POLE | ACT_FLAG_HANGING)) == 0;
|
||||
|
||||
|
@ -1916,7 +1918,7 @@ u32 interact_koopa_shell(struct MarioState *m, UNUSED u32 interactType, struct O
|
|||
u32 check_object_grab_mario(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
|
||||
if (m != &gMarioStates[0]) { return false; }
|
||||
|
||||
if ((!(m->action & (ACT_FLAG_AIR | ACT_FLAG_INVULNERABLE | ACT_FLAG_ATTACKING)) || !sInvulnerable)
|
||||
if ((!(m->action & (ACT_FLAG_AIR | ACT_FLAG_INVULNERABLE | ACT_FLAG_ATTACKING)) || !gInteractionInvulnerable)
|
||||
&& (o->oInteractionSubtype & INT_SUBTYPE_GRABS_MARIO)) {
|
||||
if (object_facing_mario(m, o, 0x2AAA)) {
|
||||
mario_stop_riding_and_holding(m);
|
||||
|
@ -2222,7 +2224,7 @@ void check_kick_or_punch_wall(struct MarioState *m) {
|
|||
|
||||
void mario_process_interactions(struct MarioState *m) {
|
||||
sDelayInvincTimer = FALSE;
|
||||
sInvulnerable = (m->action & ACT_FLAG_INVULNERABLE) || m->invincTimer != 0;
|
||||
gInteractionInvulnerable = (m->action & ACT_FLAG_INVULNERABLE) || m->invincTimer != 0;
|
||||
|
||||
if (!(m->action & ACT_FLAG_INTANGIBLE) && m->collidedObjInteractTypes != 0 && is_player_active(m)) {
|
||||
s32 i;
|
||||
|
|
|
@ -98,6 +98,7 @@ enum InteractionType {
|
|||
#define INT_STATUS_STOP_RIDING (1 << 22) /* 0x00400000 */
|
||||
#define INT_STATUS_TOUCHED_BOB_OMB (1 << 23) /* 0x00800000 */
|
||||
|
||||
extern s16 gInteractionInvulnerable;
|
||||
extern u8 gPssSlideStarted;
|
||||
|
||||
s16 mario_obj_angle_to_object(struct MarioState *m, struct Object *o);
|
||||
|
|
|
@ -176,7 +176,11 @@ void set_anim_to_frame(struct MarioState *m, s16 animFrame) {
|
|||
s32 is_anim_past_frame(struct MarioState *m, s16 animFrame) {
|
||||
s32 isPastFrame;
|
||||
s32 acceleratedFrame = animFrame << 0x10;
|
||||
|
||||
if (!m || !m->marioObj) { return TRUE; }
|
||||
struct AnimInfo *animInfo = &m->marioObj->header.gfx.animInfo;
|
||||
|
||||
if (!animInfo->curAnim) { return TRUE; }
|
||||
struct Animation *curAnim = animInfo->curAnim;
|
||||
|
||||
if (animInfo->animAccel) {
|
||||
|
|
|
@ -2282,6 +2282,8 @@ s32 cur_obj_follow_path(UNUSED s32 unusedArg) {
|
|||
f32 objToNextXZ;
|
||||
f32 objToNextX, objToNextY, objToNextZ;
|
||||
|
||||
if (o == NULL) { return PATH_NONE; }
|
||||
|
||||
if (o->oPathedPrevWaypointFlags == 0) {
|
||||
o->oPathedPrevWaypoint = o->oPathedStartWaypoint;
|
||||
o->oPathedPrevWaypointFlags = WAYPOINT_FLAGS_INITIALIZED;
|
||||
|
@ -2295,12 +2297,15 @@ s32 cur_obj_follow_path(UNUSED s32 unusedArg) {
|
|||
struct Waypoint* tmpWaypoint = (lastWaypoint + 1);
|
||||
if (tmpWaypoint == NULL) { tmpWaypoint = lastWaypoint; }
|
||||
|
||||
if (tmpWaypoint->flags != WAYPOINT_FLAGS_END) {
|
||||
if (tmpWaypoint && tmpWaypoint->flags != WAYPOINT_FLAGS_END) {
|
||||
targetWaypoint = tmpWaypoint;
|
||||
} else {
|
||||
targetWaypoint = startWaypoint;
|
||||
}
|
||||
|
||||
if (lastWaypoint == NULL) { return PATH_NONE; }
|
||||
if (targetWaypoint == NULL) { return PATH_NONE; }
|
||||
|
||||
o->oPathedPrevWaypointFlags = lastWaypoint->flags | WAYPOINT_FLAGS_INITIALIZED;
|
||||
|
||||
prevToNextX = targetWaypoint->pos[0] - lastWaypoint->pos[0];
|
||||
|
@ -2320,7 +2325,7 @@ s32 cur_obj_follow_path(UNUSED s32 unusedArg) {
|
|||
o->oPathedPrevWaypoint = targetWaypoint;
|
||||
struct Waypoint* tmpWaypoint2 = (targetWaypoint + 1);
|
||||
if (tmpWaypoint2 == NULL) { tmpWaypoint2 = targetWaypoint; }
|
||||
if (tmpWaypoint2->flags == WAYPOINT_FLAGS_END) {
|
||||
if (tmpWaypoint2 && tmpWaypoint2->flags == WAYPOINT_FLAGS_END) {
|
||||
return PATH_REACHED_END;
|
||||
} else {
|
||||
return PATH_REACHED_WAYPOINT;
|
||||
|
@ -2658,8 +2663,11 @@ s32 cur_obj_move_up_and_down(s32 a0) {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void cur_obj_call_action_function(void (*actionFunctions[])(void)) {
|
||||
void cur_obj_call_action_function(void (*actionFunctions[])(void), uint32_t actionFunctionsLength) {
|
||||
if (!actionFunctions) { return; }
|
||||
if ((uint32_t)o->oAction >= actionFunctionsLength) { return; }
|
||||
void (*actionFunction)(void) = actionFunctions[o->oAction];
|
||||
if (!actionFunction) { return; }
|
||||
actionFunction();
|
||||
}
|
||||
|
||||
|
|
|
@ -256,6 +256,8 @@ struct GraphNode_802A45E4 {
|
|||
/*0x22*/ s16 unk22;
|
||||
};
|
||||
|
||||
#define CUR_OBJ_CALL_ACTION_FUNCTION(_action_func) cur_obj_call_action_function(_action_func, (sizeof(_action_func) / sizeof(&_action_func[0])))
|
||||
|
||||
void obj_set_hitbox(struct Object *obj, struct ObjectHitbox *hitbox);
|
||||
s32 signum_positive(s32 x);
|
||||
f32 absf(f32 x);
|
||||
|
@ -273,7 +275,7 @@ void cur_obj_scale_over_time(s32 a0, s32 a1, f32 sp10, f32 sp14);
|
|||
void cur_obj_set_pos_to_home_with_debug(void);
|
||||
s32 cur_obj_is_mario_on_platform(void);
|
||||
s32 cur_obj_move_up_and_down(s32 a0);
|
||||
void cur_obj_call_action_function(void (*actionFunctions[])(void));
|
||||
void cur_obj_call_action_function(void (*actionFunctions[])(void), uint32_t actionFunctionsLength);
|
||||
void spawn_base_star_with_no_lvl_exit(void);
|
||||
s32 bit_shift_left(s32 a0);
|
||||
s32 cur_obj_mario_far_away(void);
|
||||
|
|
|
@ -337,6 +337,7 @@ void bhv_mario_update(void) {
|
|||
update_character_anim_offset(gMarioState);
|
||||
|
||||
// reset mario state to the local player
|
||||
gInteractionInvulnerable = false;
|
||||
gMarioState = &gMarioStates[0];
|
||||
}
|
||||
|
||||
|
|
|
@ -1554,7 +1554,7 @@ void geo_process_node_and_siblings(struct GraphNode *firstNode) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (curGraphNode->type == GRAPH_NODE_TYPE_OBJECT) {
|
||||
if (curGraphNode && curGraphNode->type == GRAPH_NODE_TYPE_OBJECT) {
|
||||
((struct GraphNodeObject *) curGraphNode)->throwMatrix = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ void djui_render(void) {
|
|||
gDjuiHudUtilsZ = 0;
|
||||
|
||||
create_dl_ortho_matrix();
|
||||
djui_gfx_displaylist_begin();
|
||||
|
||||
smlua_call_event_hooks(HOOK_ON_HUD_RENDER);
|
||||
|
||||
|
@ -119,4 +120,5 @@ void djui_render(void) {
|
|||
|
||||
djui_cursor_update();
|
||||
djui_interactable_update();
|
||||
djui_gfx_displaylist_end();
|
||||
}
|
||||
|
|
|
@ -4,8 +4,14 @@
|
|||
#define G_TEXOVERRIDE_DJUI 0xe0
|
||||
#define G_DJUI_SIMPLE_VERT 0x11
|
||||
#define G_DJUI_SIMPLE_TRI2 0x12
|
||||
#define G_TEXADDR_DJUI 0x13
|
||||
#define G_EXECUTE_DJUI 0xdd
|
||||
|
||||
#define gsSPTextureAddrDjui(c) \
|
||||
{{ \
|
||||
(_SHIFTL(G_TEXADDR_DJUI,24,8)|_SHIFTL(~(u32)(c),0,24)),(u32)(0) \
|
||||
}}
|
||||
|
||||
#define gSetClippingDjui(pkt, cmd, x1, y1, x2, y2) \
|
||||
{ \
|
||||
Gfx *_g = (Gfx *)(pkt); \
|
||||
|
|
|
@ -6,6 +6,25 @@
|
|||
#include "src/pc/pc_main.h"
|
||||
#include "src/pc/gfx/gfx_window_manager_api.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "djui_gfx.h"
|
||||
|
||||
const Gfx dl_djui_display_list_begin[] = {
|
||||
gsSPTextureAddrDjui(1),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
const Gfx dl_djui_display_list_end[] = {
|
||||
gsSPTextureAddrDjui(0),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
void djui_gfx_displaylist_begin(void) {
|
||||
gSPDisplayList(gDisplayListHead++, dl_djui_display_list_begin);
|
||||
}
|
||||
|
||||
void djui_gfx_displaylist_end(void) {
|
||||
gSPDisplayList(gDisplayListHead++, dl_djui_display_list_end);
|
||||
}
|
||||
|
||||
static const Vtx vertex_djui_simple_rect[] = {
|
||||
{{{ 0, -1, 0}, 0, { 0, 0 }, { 0xff, 0xff, 0xff, 0xff }}},
|
||||
|
|
|
@ -9,6 +9,9 @@ extern const Gfx dl_djui_simple_rect[];
|
|||
extern const Gfx dl_djui_img_begin[];
|
||||
extern const Gfx dl_djui_img_end[];
|
||||
|
||||
void djui_gfx_displaylist_begin(void);
|
||||
void djui_gfx_displaylist_end(void);
|
||||
|
||||
f32 djui_gfx_get_scale(void);
|
||||
|
||||
void djui_gfx_render_texture(const u8* texture, u32 w, u32 h, u32 bitSize);
|
||||
|
|
|
@ -91,6 +91,7 @@ struct InterpHud {
|
|||
f32 scaleH;
|
||||
f32 width;
|
||||
f32 height;
|
||||
enum HudUtilsResolution resolution;
|
||||
};
|
||||
static struct InterpHud sInterpHuds[MAX_INTERP_HUD] = { 0 };
|
||||
static u16 sInterpHudCount = 0;
|
||||
|
@ -102,12 +103,14 @@ void patch_djui_hud_before(void) {
|
|||
void patch_djui_hud(f32 delta) {
|
||||
f32 savedZ = gDjuiHudUtilsZ;
|
||||
Gfx* savedHeadPos = gDisplayListHead;
|
||||
enum HudUtilsResolution savedResolution = sResolution;
|
||||
for (u16 i = 0; i < sInterpHudCount; i++) {
|
||||
struct InterpHud* interp = &sInterpHuds[i];
|
||||
f32 x = delta_interpolate_f32(interp->prevX, interp->x, delta);
|
||||
f32 y = delta_interpolate_f32(interp->prevY, interp->y, delta);
|
||||
f32 scaleW = delta_interpolate_f32(interp->prevScaleW, interp->scaleW, delta);
|
||||
f32 scaleH = delta_interpolate_f32(interp->prevScaleH, interp->scaleH, delta);
|
||||
sResolution = interp->resolution;
|
||||
|
||||
gDjuiHudUtilsZ = interp->z;
|
||||
gDisplayListHead = interp->headPos;
|
||||
|
@ -125,6 +128,7 @@ void patch_djui_hud(f32 delta) {
|
|||
djui_hud_size_translate(&translatedH);
|
||||
create_dl_scale_matrix(DJUI_MTX_NOPUSH, interp->width * translatedW, interp->height * translatedH, 1.0f);
|
||||
}
|
||||
sResolution = savedResolution;
|
||||
gDisplayListHead = savedHeadPos;
|
||||
gDjuiHudUtilsZ = savedZ;
|
||||
}
|
||||
|
@ -326,6 +330,7 @@ void djui_hud_render_texture_interpolated(struct TextureInfo* texInfo, f32 prevX
|
|||
interp->width = texInfo->width;
|
||||
interp->height = texInfo->height;
|
||||
interp->z = savedZ;
|
||||
interp->resolution = sResolution;
|
||||
}
|
||||
|
||||
void djui_hud_render_texture_tile_interpolated(struct TextureInfo* texInfo, f32 prevX, f32 prevY, f32 prevScaleW, f32 prevScaleH, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH) {
|
||||
|
|
|
@ -8,16 +8,11 @@
|
|||
// events //
|
||||
////////////
|
||||
|
||||
static void djui_paginated_prev(struct DjuiBase* base) {
|
||||
struct DjuiPaginated* paginated = (struct DjuiPaginated*)base->parent;
|
||||
paginated->startIndex -= paginated->showCount;
|
||||
if (paginated->startIndex < 0) { paginated->startIndex = 0; }
|
||||
}
|
||||
|
||||
static void djui_paginated_next(struct DjuiBase* base) {
|
||||
struct DjuiPaginated* paginated = (struct DjuiPaginated*)base->parent;
|
||||
paginated->startIndex += paginated->showCount;
|
||||
static struct DjuiButton* sPrevButton = NULL;
|
||||
static struct DjuiButton* sNextButton = NULL;
|
||||
static struct DjuiText* sPageNumText = NULL;
|
||||
|
||||
static s32 djui_paginated_get_count(struct DjuiPaginated* paginated) {
|
||||
s32 count = 0;
|
||||
struct DjuiBaseChild* dbc = paginated->layout->base.child;
|
||||
while (dbc != NULL) {
|
||||
|
@ -25,6 +20,35 @@ static void djui_paginated_next(struct DjuiBase* base) {
|
|||
dbc = dbc->next;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void djui_paginated_prev(struct DjuiBase* base) {
|
||||
struct DjuiPaginated* paginated = (struct DjuiPaginated*)base->parent;
|
||||
paginated->startIndex -= paginated->showCount;
|
||||
|
||||
djui_base_set_enabled(&sPrevButton->base, (paginated->startIndex > 0));
|
||||
djui_base_set_enabled(&sNextButton->base, true);
|
||||
|
||||
char pageNumString[32] = { 0 };
|
||||
snprintf(pageNumString, 32, "%d/%d", paginated->startIndex / paginated->showCount + 1, djui_paginated_get_count(paginated) / paginated->showCount + 1);
|
||||
djui_text_set_text(sPageNumText, pageNumString);
|
||||
|
||||
if (paginated->startIndex < 0) { paginated->startIndex = 0; }
|
||||
}
|
||||
|
||||
static void djui_paginated_next(struct DjuiBase* base) {
|
||||
struct DjuiPaginated* paginated = (struct DjuiPaginated*)base->parent;
|
||||
paginated->startIndex += paginated->showCount;
|
||||
s32 count = djui_paginated_get_count(paginated);
|
||||
|
||||
djui_base_set_enabled(&sNextButton->base, (paginated->startIndex < count - 8));
|
||||
djui_base_set_enabled(&sPrevButton->base, true);
|
||||
|
||||
char pageNumString[32] = { 0 };
|
||||
snprintf(pageNumString, 32, "%d/%d", paginated->startIndex / paginated->showCount + 1, count / paginated->showCount + 1);
|
||||
djui_text_set_text(sPageNumText, pageNumString);
|
||||
|
||||
if (paginated->startIndex >= count) { paginated->startIndex -= paginated->showCount; }
|
||||
}
|
||||
|
||||
|
@ -57,6 +81,10 @@ void djui_paginated_calculate_height(struct DjuiPaginated* paginated) {
|
|||
}
|
||||
|
||||
djui_base_set_size(&paginated->base, paginated->base.width.value, height);
|
||||
|
||||
char pageNumString[32] = { 0 };
|
||||
snprintf(pageNumString, 32, "%d/%d", paginated->startIndex / paginated->showCount + 1, count / paginated->showCount + 1);
|
||||
djui_text_set_text(sPageNumText, pageNumString);
|
||||
}
|
||||
|
||||
bool djui_paginated_render(struct DjuiBase* base) {
|
||||
|
@ -112,22 +140,23 @@ struct DjuiPaginated* djui_paginated_create(struct DjuiBase* parent, u32 showCou
|
|||
paginated->layout = layout;
|
||||
}
|
||||
|
||||
{
|
||||
struct DjuiButton* button = djui_button_create(&paginated->base, "<", DJUI_BUTTON_STYLE_NORMAL, djui_paginated_prev);
|
||||
djui_base_set_alignment(&button->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
|
||||
djui_base_set_size_type(&button->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button->base, 128, 32);
|
||||
paginated->prevButton = button;
|
||||
}
|
||||
sPrevButton = djui_button_create(&paginated->base, "<", DJUI_BUTTON_STYLE_NORMAL, djui_paginated_prev);
|
||||
djui_base_set_alignment(&sPrevButton->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
|
||||
djui_base_set_size_type(&sPrevButton->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&sPrevButton->base, 128, 32);
|
||||
djui_base_set_enabled(&sPrevButton->base, false);
|
||||
paginated->prevButton = sPrevButton;
|
||||
|
||||
{
|
||||
struct DjuiButton* button = djui_button_create(&paginated->base, ">", DJUI_BUTTON_STYLE_NORMAL, djui_paginated_next);
|
||||
djui_base_set_alignment(&button->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_BOTTOM);
|
||||
djui_base_set_size_type(&button->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&button->base, 128, 32);
|
||||
djui_interactable_hook_click(&button->base, djui_paginated_next);
|
||||
paginated->nextButton = button;
|
||||
}
|
||||
sPageNumText = djui_text_create(&paginated->base, "");
|
||||
djui_base_set_color(&sPageNumText->base, 200, 200, 200, 255);
|
||||
djui_base_set_alignment(&sPageNumText->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_BOTTOM);
|
||||
sPageNumText->base.y.value -= 30;
|
||||
|
||||
sNextButton = djui_button_create(&paginated->base, ">", DJUI_BUTTON_STYLE_NORMAL, djui_paginated_next);
|
||||
djui_base_set_alignment(&sNextButton->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_BOTTOM);
|
||||
djui_base_set_size_type(&sNextButton->base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(&sNextButton->base, 128, 32);
|
||||
paginated->nextButton = sNextButton;
|
||||
|
||||
return paginated;
|
||||
}
|
||||
|
|
|
@ -189,6 +189,18 @@ static const uint8_t missing_texture[MISSING_W * MISSING_H * 4] = {
|
|||
0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
|
||||
};
|
||||
|
||||
static bool sOnlyTextureChangeOnAddrChange = false;
|
||||
|
||||
static void gfx_update_loaded_texture(uint8_t tile_number, uint32_t size_bytes, const uint8_t* addr) {
|
||||
if (!sOnlyTextureChangeOnAddrChange) {
|
||||
rdp.textures_changed[tile_number] = true;
|
||||
} else if (!rdp.textures_changed[tile_number]) {
|
||||
rdp.textures_changed[tile_number] = rdp.loaded_texture[tile_number].addr != addr;
|
||||
}
|
||||
rdp.loaded_texture[tile_number].size_bytes = size_bytes;
|
||||
rdp.loaded_texture[tile_number].addr = addr;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
// forward declaration for djui //
|
||||
//////////////////////////////////
|
||||
|
@ -210,15 +222,9 @@ static unsigned long get_time(void) {
|
|||
|
||||
static void gfx_flush(void) {
|
||||
if (buf_vbo_len > 0) {
|
||||
/*int num = buf_vbo_num_tris;
|
||||
unsigned long t0 = get_time();*/
|
||||
gfx_rapi->draw_triangles(buf_vbo, buf_vbo_len, buf_vbo_num_tris);
|
||||
buf_vbo_len = 0;
|
||||
buf_vbo_num_tris = 0;
|
||||
/*unsigned long t1 = get_time();
|
||||
if (t1 - t0 > 1000) {
|
||||
printf("f: %d %d\n", num, (int)(t1 - t0));
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1241,9 +1247,12 @@ static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t t
|
|||
rdp.texture_tile.cms = cms;
|
||||
rdp.texture_tile.cmt = cmt;
|
||||
rdp.texture_tile.line_size_bytes = line * 8;
|
||||
if (!sOnlyTextureChangeOnAddrChange) {
|
||||
// I don't know if we ever need to set these...
|
||||
rdp.textures_changed[0] = true;
|
||||
rdp.textures_changed[1] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (tile == G_TX_LOADTILE) {
|
||||
rdp.texture_to_load.tile_number = tmem / 256;
|
||||
|
@ -1256,9 +1265,12 @@ static void gfx_dp_set_tile_size(uint8_t tile, uint16_t uls, uint16_t ult, uint1
|
|||
rdp.texture_tile.ult = ult;
|
||||
rdp.texture_tile.lrs = lrs;
|
||||
rdp.texture_tile.lrt = lrt;
|
||||
if (!sOnlyTextureChangeOnAddrChange) {
|
||||
// I don't know if we ever need to set these...
|
||||
rdp.textures_changed[0] = true;
|
||||
rdp.textures_changed[1] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_dp_load_tlut(uint8_t tile, UNUSED uint32_t high_index) {
|
||||
|
@ -1290,9 +1302,7 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t
|
|||
break;
|
||||
}
|
||||
uint32_t size_bytes = (lrs + 1) << word_size_shift;
|
||||
rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes;
|
||||
rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr;
|
||||
rdp.textures_changed[rdp.texture_to_load.tile_number] = true;
|
||||
gfx_update_loaded_texture(rdp.texture_to_load.tile_number, size_bytes, rdp.texture_to_load.addr);
|
||||
}
|
||||
|
||||
static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, uint32_t lrt) {
|
||||
|
@ -1318,15 +1328,11 @@ static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t
|
|||
}
|
||||
|
||||
uint32_t size_bytes = (((lrs >> G_TEXTURE_IMAGE_FRAC) + 1) * ((lrt >> G_TEXTURE_IMAGE_FRAC) + 1)) << word_size_shift;
|
||||
rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes;
|
||||
|
||||
rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr;
|
||||
gfx_update_loaded_texture(rdp.texture_to_load.tile_number, size_bytes, rdp.texture_to_load.addr);
|
||||
rdp.texture_tile.uls = uls;
|
||||
rdp.texture_tile.ult = ult;
|
||||
rdp.texture_tile.lrs = lrs;
|
||||
rdp.texture_tile.lrt = lrt;
|
||||
|
||||
rdp.textures_changed[rdp.texture_to_load.tile_number] = true;
|
||||
}
|
||||
|
||||
static uint8_t color_comb_component(uint32_t v) {
|
||||
|
@ -1977,10 +1983,7 @@ static void OPTIMIZE_O3 djui_gfx_dp_execute_override(void) {
|
|||
uint32_t wordSizeShift = (sDjuiOverrideB == 32) ? 2 : 1;
|
||||
uint32_t lrs = (sDjuiOverrideW * sDjuiOverrideH) - 1;
|
||||
uint32_t sizeBytes = (lrs + 1) << wordSizeShift;
|
||||
rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = sizeBytes;
|
||||
rdp.textures_changed[rdp.texture_to_load.tile_number] = rdp.loaded_texture[rdp.texture_to_load.tile_number].addr != rdp.texture_to_load.addr;
|
||||
rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr;
|
||||
//rdp.textures_changed[rdp.texture_to_load.tile_number] = true;
|
||||
gfx_update_loaded_texture(rdp.texture_to_load.tile_number, sizeBytes, rdp.texture_to_load.addr);
|
||||
|
||||
// gsDPSetTile
|
||||
uint32_t line = (((sDjuiOverrideW * 2) + 7) >> 3);
|
||||
|
@ -2135,6 +2138,9 @@ void OPTIMIZE_O3 djui_gfx_run_dl(Gfx* cmd) {
|
|||
djui_gfx_sp_simple_tri1(C0(16, 8) / 2, C0(8, 8) / 2, C0(0, 8) / 2);
|
||||
djui_gfx_sp_simple_tri1(C1(16, 8) / 2, C1(8, 8) / 2, C1(0, 8) / 2);
|
||||
break;
|
||||
case G_TEXADDR_DJUI:
|
||||
sOnlyTextureChangeOnAddrChange = !(C0(0, 24) & 0x01);
|
||||
break;
|
||||
case G_EXECUTE_DJUI:
|
||||
djui_gfx_dp_execute_djui(cmd->words.w1);
|
||||
break;
|
||||
|
|
|
@ -4016,7 +4016,7 @@ char gSmluaConstants[] = ""
|
|||
"COOP_OBJ_FLAG_INITIALIZED = (1 << 3)\n"
|
||||
"VERSION_TEXT = 'beta'\n"
|
||||
"VERSION_NUMBER = 33\n"
|
||||
"MINOR_VERSION_NUMBER = 0\n"
|
||||
"MINOR_VERSION_NUMBER = 1\n"
|
||||
"PATCH_VERSION_NUMBER = 0\n"
|
||||
"MAX_VERSION_LENGTH = 10\n"
|
||||
"MAX_LOCAL_VERSION_LENGTH = 12\n"
|
||||
|
|
|
@ -473,66 +473,104 @@ struct LuaLevelScriptParse {
|
|||
struct LuaLevelScriptParse sLevelScriptParse = { 0 };
|
||||
|
||||
s32 smlua_func_level_script_parse_callback(u8 type, void *cmd) {
|
||||
if (type != 0x24 && type != 0x39 && type != 0x1F) {
|
||||
return 0;
|
||||
u32 areaIndex, bhvId, bhvArgs;
|
||||
u32 *pAreaIndex = NULL, *pBhvId = NULL, *pBhvArgs = NULL;
|
||||
MacroObject *pMacroData = NULL;
|
||||
|
||||
// Gather arguments
|
||||
switch (type) {
|
||||
|
||||
// AREA
|
||||
case 0x1F: {
|
||||
areaIndex = (u8) dynos_level_cmd_get(cmd, 2);
|
||||
pAreaIndex = &areaIndex;
|
||||
} break;
|
||||
|
||||
// OBJECT_WITH_ACTS
|
||||
case 0x24: {
|
||||
const BehaviorScript *bhv = (const BehaviorScript *) dynos_level_cmd_get(cmd, 20);
|
||||
if (bhv) {
|
||||
bhvId = (u32) get_id_from_behavior(bhv);
|
||||
bhvArgs = (u32) dynos_level_cmd_get(cmd, 16);
|
||||
pBhvId = &bhvId;
|
||||
pBhvArgs = &bhvArgs;
|
||||
}
|
||||
} break;
|
||||
|
||||
// OBJECT_WITH_ACTS_EXT
|
||||
case 0x3F: {
|
||||
const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 20));
|
||||
if (bhvStr) {
|
||||
bhvId = (u32) smlua_get_any_integer_mod_variable(bhvStr);
|
||||
bhvArgs = (u32) dynos_level_cmd_get(cmd, 16);
|
||||
pBhvId = &bhvId;
|
||||
pBhvArgs = &bhvArgs;
|
||||
}
|
||||
} break;
|
||||
|
||||
// OBJECT_WITH_ACTS_EXT2
|
||||
case 0x40: {
|
||||
const char *bhvStr = dynos_level_get_token(dynos_level_cmd_get(cmd, 24));
|
||||
if (bhvStr) {
|
||||
bhvId = (u32) smlua_get_any_integer_mod_variable(bhvStr);
|
||||
bhvArgs = (u32) dynos_level_cmd_get(cmd, 16);
|
||||
pBhvId = &bhvId;
|
||||
pBhvArgs = &bhvArgs;
|
||||
}
|
||||
} break;
|
||||
|
||||
// MACRO_OBJECTS
|
||||
case 0x39: {
|
||||
pMacroData = (MacroObject *) dynos_level_cmd_get(cmd, 4);
|
||||
} break;
|
||||
|
||||
// None of the above
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
// Retrieve Lua state
|
||||
lua_State* L = gLuaState;
|
||||
if (L == NULL) { return 0; }
|
||||
struct LuaLevelScriptParse* preprocess = &sLevelScriptParse;
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, preprocess->reference);
|
||||
|
||||
if (type == 0x1F) {
|
||||
u8 area = (u8) dynos_level_cmd_get(cmd, 2);
|
||||
lua_pushinteger(L, area);
|
||||
// Push 'areaIndex'
|
||||
if (pAreaIndex) {
|
||||
lua_pushinteger(L, *pAreaIndex);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
if (type == 0x24) {
|
||||
const BehaviorScript *bhv = (const BehaviorScript *) dynos_level_cmd_get(cmd, 20);
|
||||
u32 behaviorArg = (u32) dynos_level_cmd_get(cmd, 16);
|
||||
|
||||
// Push 'bhvData'
|
||||
if (pBhvId && pBhvArgs) {
|
||||
lua_newtable(L);
|
||||
|
||||
lua_pushstring(L, "behavior");
|
||||
lua_pushinteger(L, get_id_from_behavior(bhv));
|
||||
lua_pushinteger(L, *pBhvId);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "behaviorArg");
|
||||
lua_pushinteger(L, behaviorArg);
|
||||
lua_pushinteger(L, *pBhvArgs);
|
||||
lua_settable(L, -3);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
if (type == 0x39) {
|
||||
MacroObject *data = (MacroObject *) dynos_level_cmd_get(cmd, 4);
|
||||
int i = 0;
|
||||
s32 len = 0;
|
||||
|
||||
// Push 'macroBhvIds' and 'macroBhvArgs'
|
||||
if (pMacroData) {
|
||||
lua_newtable(L);
|
||||
int t = lua_gettop(gLuaState);
|
||||
|
||||
s32 macroBhvIdsIdx = lua_gettop(gLuaState);
|
||||
lua_newtable(L);
|
||||
int args = lua_gettop(gLuaState);
|
||||
while (data[len++] != MACRO_OBJECT_END()) {
|
||||
s32 presetId = (s32) ((data[len - 1] & 0x1FF) - 0x1F);
|
||||
const BehaviorScript *bhv = (const BehaviorScript *) MacroObjectPresets[presetId].behavior;
|
||||
s32 macroBhvArgsIdx = lua_gettop(gLuaState);
|
||||
for (s32 i = 0; *pMacroData != MACRO_OBJECT_END(); pMacroData += 5, i++) {
|
||||
s32 presetId = (s32) ((pMacroData[0] & 0x1FF) - 0x1F);
|
||||
s32 presetParams = MacroObjectPresets[presetId].param;
|
||||
s32 objParams = (data[4] & 0xFF00) + (presetParams & 0x00FF);
|
||||
u32 behaviorArg = ((objParams & 0x00FF) << 16) + (objParams & 0xFF00);
|
||||
|
||||
s32 objParams = (pMacroData[4] & 0xFF00) | (presetParams & 0x00FF);
|
||||
s32 bhvParams = ((objParams & 0x00FF) << 16) | (objParams & 0xFF00);
|
||||
lua_pushinteger(L, i);
|
||||
lua_pushinteger(L, get_id_from_behavior(bhv));
|
||||
lua_settable(L, t);
|
||||
|
||||
lua_pushinteger(L, get_id_from_behavior(MacroObjectPresets[presetId].behavior));
|
||||
lua_settable(L, macroBhvIdsIdx);
|
||||
lua_pushinteger(L, i);
|
||||
lua_pushinteger(L, behaviorArg);
|
||||
lua_settable(L, args);
|
||||
|
||||
i++;
|
||||
len += 4;
|
||||
lua_pushinteger(L, bhvParams);
|
||||
lua_settable(L, macroBhvArgsIdx);
|
||||
}
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
|
|
|
@ -271,8 +271,12 @@ static bool smlua_sync_table_send_field(u8 toLocalIndex, int stackIndex, bool al
|
|||
|
||||
// send over the network
|
||||
if (!gLuaInitializingScript) {
|
||||
if (sUnwoundLntsCount < 2) {
|
||||
LOG_ERROR("Sent sync table field packet with an invalid key count: %u", sUnwoundLntsCount);
|
||||
} else {
|
||||
network_send_lua_sync_table(toLocalIndex, seq, modRemoteIndex, sUnwoundLntsCount, sUnwoundLnts, &lntValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////
|
||||
|
@ -311,6 +315,12 @@ void smlua_set_sync_table_field_from_network(u64 seq, u16 modRemoteIndex, u16 ln
|
|||
return;
|
||||
}
|
||||
|
||||
// sanity check key count
|
||||
if (lntKeyCount < 2) {
|
||||
LOG_ERROR("Received sync table field packet with an invalid key count: %u", lntKeyCount);
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getglobal(L, "_G"); // get global table
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath); // get the file's "global" table
|
||||
lua_remove(L, -2); // remove global table
|
||||
|
|
|
@ -152,6 +152,9 @@ void mod_activate(struct Mod* mod) {
|
|||
}
|
||||
|
||||
void mod_clear(struct Mod* mod) {
|
||||
if (!mod) { return; }
|
||||
|
||||
if (mod->files) {
|
||||
for (int j = 0; j < mod->fileCount; j++) {
|
||||
struct ModFile* file = &mod->files[j];
|
||||
if (file->fp != NULL) {
|
||||
|
@ -163,6 +166,7 @@ void mod_clear(struct Mod* mod) {
|
|||
file->cachedPath = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mod->name != NULL) {
|
||||
free(mod->name);
|
||||
|
@ -437,15 +441,10 @@ bool mod_load(struct Mods* mods, char* basePath, char* modName) {
|
|||
valid = true;
|
||||
} else if (is_directory(fullPath)) {
|
||||
char tmpPath[SYS_MAX_PATH] = { 0 };
|
||||
char path1[SYS_MAX_PATH] = { 0 };
|
||||
char path2[SYS_MAX_PATH] = { 0 };
|
||||
if (!concat_path(tmpPath, fullPath, "main.lua")) {
|
||||
LOG_ERROR("Failed to concat path '%s' + '%s'", fullPath, "main.lua");
|
||||
return true;
|
||||
}
|
||||
if ((concat_path(path1, fullPath, "c-update.lua") && path_exists(path1)) || (concat_path(path2, fullPath, "m-update.lua") && path_exists(path2))) {
|
||||
return true;
|
||||
}
|
||||
valid = path_exists(tmpPath);
|
||||
}
|
||||
|
||||
|
@ -513,13 +512,11 @@ bool mod_load(struct Mods* mods, char* basePath, char* modName) {
|
|||
|
||||
// print
|
||||
LOG_INFO(" %s", mod->name);
|
||||
if (isDirectory) {
|
||||
for (int i = 0; i < mod->fileCount; i++) {
|
||||
struct ModFile* file = &mod->files[i];
|
||||
mod_cache_add(mod, file, true);
|
||||
LOG_INFO(" - %s", file->relativePath);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ static bool mod_import_lua(char* src) {
|
|||
static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) {
|
||||
LOG_INFO("Importing zip mod: %s", path);
|
||||
|
||||
char luaPath[SYS_MAX_PATH] = { 0 };
|
||||
mz_zip_archive zip_archive = { 0 };
|
||||
mz_bool status = mz_zip_reader_init_file(&zip_archive, path, 0);
|
||||
if (!status) {
|
||||
|
@ -75,6 +76,7 @@ static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) {
|
|||
}
|
||||
|
||||
if (str_ends_with(file_stat.m_filename, ".lua")) {
|
||||
path_get_folder(file_stat.m_filename, luaPath);
|
||||
*isLua = true;
|
||||
break;
|
||||
} else if (str_ends_with(file_stat.m_filename, ".tex")) {
|
||||
|
@ -99,12 +101,32 @@ static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) {
|
|||
snprintf(dstDirectory, SYS_MAX_PATH, "%s", (char*)fs_get_write_path(DYNOS_PACKS_FOLDER));
|
||||
} else {
|
||||
LOG_ERROR("Could not figure out what type of mod this is");
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return false;
|
||||
}
|
||||
|
||||
// create mod/dynos path if it doesn't exist
|
||||
if (!fs_sys_dir_exists(dstDirectory)) {
|
||||
fs_sys_mkdir(dstDirectory);
|
||||
}
|
||||
|
||||
// erase and create lua path
|
||||
if (*isLua && strlen(luaPath) > 0) {
|
||||
if (!concat_path(dst, dstDirectory, luaPath)) {
|
||||
LOG_ERROR("Failed to concat path for base lua directory");
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return false;
|
||||
}
|
||||
if (fs_sys_dir_exists(dst)) {
|
||||
mods_delete_folder(dst);
|
||||
}
|
||||
if (!fs_sys_mkdir(dst)) {
|
||||
LOG_ERROR("Failed to mkdir for base lua directory");
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the archive
|
||||
for (int i = 0; i < (int)mz_zip_reader_get_num_files(&zip_archive); i++) {
|
||||
mz_zip_archive_file_stat file_stat;
|
||||
|
@ -159,6 +181,8 @@ static bool mod_import_zip(char* path, bool* isLua, bool* isDynos) {
|
|||
FILE* fout = fopen(dst, "wb");
|
||||
if (fout == NULL) {
|
||||
LOG_ERROR("Failed to open dst path for zip mod import");
|
||||
mz_free((void*)p);
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -132,6 +132,16 @@ void discord_activity_update(bool hosting) {
|
|||
LOGFILE_INFO(LFT_DISCORD, "truncating details");
|
||||
}
|
||||
|
||||
if (!app.activities) {
|
||||
LOGFILE_INFO(LFT_DISCORD, "no activities");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!app.activities->update_activity) {
|
||||
LOGFILE_INFO(LFT_DISCORD, "no update_activity");
|
||||
return;
|
||||
}
|
||||
|
||||
app.activities->update_activity(app.activities, &gCurActivity, NULL, on_activity_update_callback);
|
||||
LOGFILE_INFO(LFT_DISCORD, "set activity");
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "behavior_table.h"
|
||||
#include "model_ids.h"
|
||||
|
||||
#define MAX_LOCAL_STATE_HISTORY 20
|
||||
#define MAX_LOCAL_STATE_HISTORY 30
|
||||
struct StateHistory {
|
||||
struct MarioState m;
|
||||
struct Object marioObj;
|
||||
|
@ -40,16 +40,16 @@ void lag_compensation_store(void) {
|
|||
}
|
||||
|
||||
struct MarioState* lag_compensation_get_local_state(struct NetworkPlayer* otherNp) {
|
||||
if (!otherNp) { return NULL; }
|
||||
if (gNetworkType == NT_NONE) { return NULL; }
|
||||
if (!sLocalStateHistoryReady) { return NULL; }
|
||||
if (!otherNp) { return &gMarioStates[0]; }
|
||||
if (gNetworkType == NT_NONE) { return &gMarioStates[0]; }
|
||||
if (!sLocalStateHistoryReady) { return &gMarioStates[0]; }
|
||||
|
||||
s32 pingToTicks = (otherNp->ping / 1000.0f) * 30;
|
||||
if (pingToTicks > (MAX_LOCAL_STATE_HISTORY-1)) {
|
||||
pingToTicks = (MAX_LOCAL_STATE_HISTORY-1);
|
||||
}
|
||||
//LOG_INFO("Ping: %s :: %u :: %d", otherNp->name, otherNp->ping, pingToTicks);
|
||||
if (pingToTicks == 0) { return NULL; }
|
||||
if (pingToTicks == 0) { return &gMarioStates[0]; }
|
||||
|
||||
s32 index = (s32)sLocalStateHistoryIndex - pingToTicks;
|
||||
while (index < 0) { index += MAX_LOCAL_STATE_HISTORY; }
|
||||
|
|
|
@ -52,8 +52,8 @@ void packet_process(struct Packet* p) {
|
|||
case PACKET_JOIN: network_receive_join(p); break;
|
||||
case PACKET_CHAT: network_receive_chat(p); break;
|
||||
case PACKET_KICK: network_receive_kick(p); break;
|
||||
case PACKET_COMMAND: network_recieve_chat_command(p); break;
|
||||
case PACKET_MODERATOR: network_recieve_moderator(p); break;
|
||||
case PACKET_COMMAND: network_receive_chat_command(p); break;
|
||||
case PACKET_MODERATOR: network_receive_moderator(p); break;
|
||||
case PACKET_KEEP_ALIVE: network_receive_keep_alive(p); break;
|
||||
case PACKET_LEAVING: network_receive_leaving(p); break;
|
||||
case PACKET_SAVE_FILE: network_receive_save_file(p); break;
|
||||
|
|
|
@ -234,11 +234,11 @@ void network_receive_kick(struct Packet* p);
|
|||
|
||||
// packet_command_mod.c
|
||||
void network_send_chat_command(u8 localIndex, enum ChatConfirmCommand CCC);
|
||||
void network_recieve_chat_command(struct Packet* p);
|
||||
void network_receive_chat_command(struct Packet* p);
|
||||
|
||||
// packet_moderator.c
|
||||
void network_send_moderator(u8 localIndex);
|
||||
void network_recieve_moderator(struct Packet* p);
|
||||
void network_receive_moderator(struct Packet* p);
|
||||
|
||||
// packet_keep_alive.c
|
||||
void network_send_keep_alive(u8 localIndex);
|
||||
|
|
|
@ -138,7 +138,7 @@ void network_receive_area(struct Packet* p) {
|
|||
LOG_INFO("rx area");
|
||||
|
||||
if (p == NULL) {
|
||||
LOG_ERROR("rx area: the packet was NULL, failed to recieve the area.");
|
||||
LOG_ERROR("rx area: the packet was NULL, failed to receive the area.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ void network_send_chat_command(u8 globalIndex, enum ChatConfirmCommand ccc) {
|
|||
}
|
||||
}
|
||||
|
||||
void network_recieve_chat_command(struct Packet *p) {
|
||||
void network_receive_chat_command(struct Packet *p) {
|
||||
if (!moderator_list_contains(gNetworkSystem->get_id_str(p->localIndex))) {
|
||||
return;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ void network_send_moderator(u8 localIndex) {
|
|||
network_send_to(localIndex, &p);
|
||||
}
|
||||
|
||||
void network_recieve_moderator(struct Packet *p) {
|
||||
void network_receive_moderator(struct Packet *p) {
|
||||
if ((gIsModerator) || (network_player_any_connected() && gNetworkPlayers[p->localIndex].type != NPT_SERVER)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -332,6 +332,11 @@ static void open_mod_file(struct Mod* mod, struct ModFile* file) {
|
|||
}
|
||||
|
||||
void network_receive_download(struct Packet* p) {
|
||||
if (!p) {
|
||||
LOG_ERROR("Received null packet");
|
||||
return;
|
||||
}
|
||||
|
||||
SOFT_ASSERT(gNetworkType == NT_CLIENT);
|
||||
if (p->localIndex != UNKNOWN_LOCAL_INDEX) {
|
||||
if (gNetworkPlayerServer == NULL || gNetworkPlayerServer->localIndex != p->localIndex) {
|
||||
|
@ -343,9 +348,13 @@ void network_receive_download(struct Packet* p) {
|
|||
// read the chunk
|
||||
u64 receiveOffset = 0;
|
||||
u64 chunkLength = 0;
|
||||
u8 chunk[CHUNK_SIZE] = { 0 };
|
||||
u8 chunk[CHUNK_SIZE+1] = { 0 };
|
||||
packet_read(p, &receiveOffset, sizeof(u64));
|
||||
packet_read(p, &chunkLength, sizeof(u64));
|
||||
if (chunkLength > CHUNK_SIZE) {
|
||||
LOG_ERROR("Received improper chunk length");
|
||||
return;
|
||||
}
|
||||
packet_read(p, &chunk, sizeof(u8) * chunkLength);
|
||||
|
||||
// mark the offset group as received
|
||||
|
@ -379,6 +388,10 @@ after_group:;
|
|||
u64 fileStartOffset = 0;
|
||||
for (u64 modIndex = 0; modIndex < gRemoteMods.entryCount; modIndex++) {
|
||||
struct Mod* mod = gRemoteMods.entries[modIndex];
|
||||
if (!mod) {
|
||||
LOG_ERROR("Null mod");
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip past mods to get to the right offset
|
||||
if ((fileStartOffset + mod->size) < receiveOffset) {
|
||||
|
@ -386,6 +399,11 @@ after_group:;
|
|||
continue;
|
||||
}
|
||||
|
||||
if (mod->fileCount > 0 && !mod->files) {
|
||||
LOG_ERROR("Null mod files");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (u64 fileIndex = 0; fileIndex < mod->fileCount; fileIndex++) {
|
||||
struct ModFile* modFile = &mod->files[fileIndex];
|
||||
|
||||
|
|
|
@ -11,6 +11,11 @@ void network_send_lua_custom(bool broadcast) {
|
|||
u16 zero = 0;
|
||||
s32 paramIndex = 1;
|
||||
|
||||
if (!L) {
|
||||
LOG_ERROR("Sent lua custom packet when lua is dead");
|
||||
return;
|
||||
}
|
||||
|
||||
// figure out mod index
|
||||
if (gLuaActiveMod == NULL) {
|
||||
LOG_LUA_LINE("Could not figure out the current active mod!");
|
||||
|
@ -99,6 +104,11 @@ void network_receive_lua_custom(struct Packet* p) {
|
|||
packet_read(p, &modIndex, sizeof(u16));
|
||||
packet_read(p, &keyCount, sizeof(u8));
|
||||
|
||||
if (!L) {
|
||||
LOG_ERROR("Received lua custom packet when lua is dead");
|
||||
return;
|
||||
}
|
||||
|
||||
lua_newtable(L);
|
||||
s32 tableIndex = lua_gettop(L);
|
||||
for(u16 i = 0; i < keyCount; i++) {
|
||||
|
|
|
@ -36,6 +36,7 @@ void network_send_lua_sync_table(u8 toLocalIndex, u64 seq, u16 modRemoteIndex, u
|
|||
//LOG_INFO(" %s", smlua_lnt_to_str(&lntKeys[i]));
|
||||
}
|
||||
//LOG_INFO(" -> %s", smlua_lnt_to_str(lntValue));
|
||||
//LOG_INFO(" count %u", lntKeyCount);
|
||||
|
||||
if (!packet_write_lnt(&p, lntValue)) { return; }
|
||||
|
||||
|
@ -66,6 +67,7 @@ void network_receive_lua_sync_table(struct Packet* p) {
|
|||
//LOG_INFO(" %s", smlua_lnt_to_str(&lntKeys[i]));
|
||||
}
|
||||
//LOG_INFO(" -> %s", smlua_lnt_to_str(&lntValue));
|
||||
//LOG_INFO(" count %u", lntKeyCount);
|
||||
|
||||
if (!packet_read_lnt(p, &lntValue)) { goto cleanup; }
|
||||
|
||||
|
|
|
@ -28,7 +28,10 @@ void network_send_mod_list_request(void) {
|
|||
}
|
||||
|
||||
void network_receive_mod_list_request(UNUSED struct Packet* p) {
|
||||
SOFT_ASSERT(gNetworkType == NT_SERVER);
|
||||
if (gNetworkType != NT_SERVER) {
|
||||
LOG_ERROR("Network type should be server!");
|
||||
return;
|
||||
}
|
||||
LOG_INFO("received mod list request");
|
||||
|
||||
network_send_mod_list();
|
||||
|
|
|
@ -59,6 +59,11 @@ void network_send_spawn_objects_to(u8 sendToLocalIndex, struct Object* objects[]
|
|||
return;
|
||||
}
|
||||
|
||||
if (objectCount == 0) {
|
||||
LOG_ERROR("Tried to send 0 objects");
|
||||
return;
|
||||
}
|
||||
|
||||
SOFT_ASSERT(objectCount < MAX_SPAWN_OBJECTS_PER_PACKET);
|
||||
// prevent sending spawn objects during credits
|
||||
if (gCurrActStarNum == 99) {
|
||||
|
@ -74,6 +79,11 @@ void network_send_spawn_objects_to(u8 sendToLocalIndex, struct Object* objects[]
|
|||
|
||||
for (u8 i = 0; i < objectCount; i++) {
|
||||
struct Object* o = objects[i];
|
||||
if (!o) {
|
||||
LOG_ERROR("Tried to send null object");
|
||||
return;
|
||||
}
|
||||
|
||||
u32 model = models[i];
|
||||
u32 parentId = generate_parent_id(objects, i, true);
|
||||
u32 behaviorId = get_id_from_behavior(o->behavior);
|
||||
|
@ -96,11 +106,15 @@ void network_send_spawn_objects_to(u8 sendToLocalIndex, struct Object* objects[]
|
|||
|
||||
if (sendToLocalIndex == PACKET_DESTINATION_BROADCAST) {
|
||||
network_send(&p);
|
||||
if (objects[0] && objects[0]->behavior) {
|
||||
LOG_INFO("tx spawn objects (BROADCAST) | %u", get_id_from_behavior(objects[0]->behavior));
|
||||
}
|
||||
} else {
|
||||
network_send_to(sendToLocalIndex, &p);
|
||||
if (objects[0] && objects[0]->behavior) {
|
||||
LOG_INFO("tx spawn objects to %d | %u", gNetworkPlayers[sendToLocalIndex].globalIndex, get_id_from_behavior(objects[0]->behavior));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void network_receive_spawn_objects(struct Packet* p) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#define VERSION_TEXT "beta"
|
||||
#define VERSION_NUMBER 33
|
||||
#define MINOR_VERSION_NUMBER 0
|
||||
#define MINOR_VERSION_NUMBER 1
|
||||
#define PATCH_VERSION_NUMBER 0
|
||||
|
||||
#define MAX_VERSION_LENGTH 10
|
||||
|
|
|
@ -14,6 +14,7 @@ u64 osClockRate = 62500000;
|
|||
s32 osPiStartDma(UNUSED OSIoMesg *mb, UNUSED s32 priority, UNUSED s32 direction,
|
||||
uintptr_t devAddr, void *vAddr, size_t nbytes,
|
||||
UNUSED OSMesgQueue *mq) {
|
||||
if (!vAddr || !devAddr) { return 0; }
|
||||
memcpy(vAddr, (const void *) devAddr, nbytes);
|
||||
return 0;
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 9.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.1 KiB |
Loading…
Reference in a new issue