[VC] 2 player / 2 Jogadores / Coop v0.3 Alpha
Enviado: 03 Dez 2019, 09:53
Greetings from Vice city!
Desde novembro estou tentando extrair leite de pedra ao fazer um mod de dois jogadores para o GTA: VC.
Já consegui fazer a câmera funcionar de maneira legal e o jogador 2 se mover em relação à câmera.
Estou implementando outras funções e vocês irão ver esses leftovers (sobras) no código. Apenas ignore-os. Outras funções não estão otimizadas/bem-feitas, também ignore isso (tipo se agachar. Eu vou melhorar para ser um toggle, em vez de enquanto estiver pressionado. Tenham fé, eu sou baiano, as coisas têm que ser devagar
. Eu estava focando em outras coisas e deixei de lado isso, apesar de ser mega simples de resolver).
Vou deixar só o código aqui. Coloco o .cs (cleo script compilado) hoje à noite, quando eu chegar em casa.
MUITA coisa ainda precisa melhorar (tal qual eu utilizar uma função para verificar se o handle do scplayer é válido e aí sim retornar um bit positivo, em vez de gastar uma variável para saber se está rolando um jogo 2 players, no caso, p2stat)
Sim, muita coisa precisa melhorar e talvez eu não consiga fazer algo legal pelas limitações do CLEO, mas vou tentar. Sabe como uma formiga come um elefante? Comendo um pedacinho de cada vez. Se preciso for (e estiver dentro das minhas capacidades) irei estudar LUA ou mesmo C++ para modificar mais a fundo o jogo.
Forte abraço a todos!
Desde novembro estou tentando extrair leite de pedra ao fazer um mod de dois jogadores para o GTA: VC.
Já consegui fazer a câmera funcionar de maneira legal e o jogador 2 se mover em relação à câmera.
Estou implementando outras funções e vocês irão ver esses leftovers (sobras) no código. Apenas ignore-os. Outras funções não estão otimizadas/bem-feitas, também ignore isso (tipo se agachar. Eu vou melhorar para ser um toggle, em vez de enquanto estiver pressionado. Tenham fé, eu sou baiano, as coisas têm que ser devagar
. Eu estava focando em outras coisas e deixei de lado isso, apesar de ser mega simples de resolver).Vou deixar só o código aqui. Coloco o .cs (cleo script compilado) hoje à noite, quando eu chegar em casa.
SpoilerAbrir
Código: Selecionar tudo
SCRIPT_START
{
NOP
LVAR_FLOAT x y z //coordenadas
LVAR_FLOAT a b c //coordenadas auxiliares (para fazer comparação, etc)
LVAR_FLOAT dist //usado para tirar a distância entre as coordenadas
LVAR_FLOAT angle c_angle //ângulo de char/player e da câmera
// LVAR_INT p2health //saúde do jogador 2
LVAR_INT scplayer scplayer2 //handle dos jogadores
LVAR_INT mirando alvo
LVAR_INT misc
LVAR_INT p2stat //status do jogo 2 player
p2stat = 0
GET_PLAYER_CHAR 0 scplayer
inicio:
WAIT 0
IF IS_KEY_PRESSED VK_F10
GOSUB start2p
ENDIF
IF p2stat = 1
GOSUB andar
GOSUB camera
CLEO_CALL camera_angle, 0, c_angle c_angle
GOSUB morto
GOSUB mirar
//GOSUB carro
ENDIF
GOTO inicio
start2p:
IF p2stat = 0
SET_INTERPOLATION_PARAMETERS 0.0 100 //isso é para a câmera não ficar pulando (transição suave)
REQUEST_MODEL CLA
WHILE NOT HAS_MODEL_LOADED CLA
WAIT 0
ENDWHILE
GET_PLAYER_COORDINATES 0 x, y, z
y += 5.0
CREATE_CHAR 1, CLA, x, y, z, scplayer2
GIVE_WEAPON_TO_CHAR scplayer2, WEAPONTYPE_PISTOL, 60
PRINT_FORMATTED "2 player ativado!", 2000
ADD_ONE_OFF_SOUND x, y, z, SOUND_PART_MISSION_COMPLETE
CHAR_SET_IDLE scplayer2
SET_CHAR_AS_PLAYER_FRIEND scplayer2, 0, 1
SET_CHAR_NEVER_TARGETTED scplayer2, 1
p2stat = 1
WHILE IS_KEY_PRESSED VK_F10
WAIT 0
ENDWHILE
ENDIF
RETURN
andar:
IF NOT IS_CHAR_IN_ANY_CAR scplayer2
IF IS_KEY_PRESSED VK_KEY_I // N
angle = 0.0
ENDIF
IF IS_KEY_PRESSED VK_KEY_J // W
angle = 90.0
ENDIF
IF IS_KEY_PRESSED VK_KEY_K // S
angle = 180.0
ENDIF
IF IS_KEY_PRESSED VK_KEY_L // E
angle = -90.0
ENDIF
IF IS_KEY_PRESSED VK_KEY_I // NW
AND IS_KEY_PRESSED VK_KEY_J
angle = 45.0
ENDIF
IF IS_KEY_PRESSED VK_KEY_I // NE
AND IS_KEY_PRESSED VK_KEY_L
angle = -45.0
ENDIF
IF IS_KEY_PRESSED VK_KEY_J // N
AND IS_KEY_PRESSED VK_KEY_K
angle = 135.0
ENDIF
IF IS_KEY_PRESSED VK_KEY_K // N
AND IS_KEY_PRESSED VK_KEY_L
angle = -135.0
ENDIF
IF IS_KEY_PRESSED VK_KEY_I
OR IS_KEY_PRESSED VK_KEY_J
OR IS_KEY_PRESSED VK_KEY_K
OR IS_KEY_PRESSED VK_KEY_L
GET_CHAR_COORDINATES scplayer2, x, y, z //movimentação relativa à câmera.
angle += c_angle
COS angle, a //Também trigonometria básica.
SIN angle, b //Se usa o ângulo da câmera para decompor as resultantes x e y
a *= 0.7
b *= 0.7
x -= a //e aplica os valores relativos à câmera às coordenadas do mundo.
y -= b
SET_CHAR_OBJ_SPRINT_TO_COORD scplayer2 x, y
ENDIF
IF IS_KEY_PRESSED VK_KEY_B
SET_CHAR_CROUCH scplayer2, 1, 100
ENDIF
ENDIF
RETURN
camera:
WAIT 0
//essa parte é pra câmera sempre apontar para o ponto entre os dois jogadores
GET_CHAR_COORDINATES scplayer, a, b, c
GET_CHAR_COORDINATES scplayer2, x, y, z
GET_DISTANCE_BETWEEN_COORDS_2D a, b, x, y, dist //já aproveito pra tirar a distância também, pois vai ser usada na próxima parte, sem necessidade de se obter as coordenadas de novo
x += a //aqui vai ser tirada a média das coordenadas. Somar e dividir pela quantidade de elementos (no caso 2)
y += b
z += c
x /= 2.0
y /= 2.0
z /= 2.0
POINT_CAMERA_AT_POINT x, y, z, 1
// aqui, é para definir o raio da câmera, bem como sua posição. Baseado em trigonometria básica
COS c_angle, a
SIN c_angle, b
dist *= 1.1 //a câmera estava ficando muito perto quando os jogadores estavam próximos
a *= dist
b *= dist
x += a
y += b
dist *= 0.05 //isso é pra fazer a câmera subir um pouco quando os personagem se afastam
z *= dist
z += 12.0
SET_FIXED_CAMERA_POSITION x, y, z, 0.0, 0.0, 0.0
RETURN
morto:
IF IS_PLAYER_DEAD 0
OR IS_CHAR_DEAD scplayer2
OR IS_KEY_PRESSED VK_F10
RESTORE_CAMERA
REMOVE_CHAR_ELEGANTLY scplayer2
PRINT_FORMATTED "2 player desativado!", 2000
ADD_ONE_OFF_SOUND x, y, z, SOUND_PART_MISSION_COMPLETE
p2stat = 0
WHILE IS_KEY_PRESSED VK_F10
WAIT 0
ENDWHILE
ENDIF
RETURN
mirar: //ainda está sendo escrito e polido
IF IS_KEY_PRESSED VK_KEY_Y //tecla de mirar
GET_CHAR_COORDINATES scplayer2 x, y, z
GET_RANDOM_CHAR_IN_SPHERE_NO_SAVE_RECURSIVE x, y, z, 20.0, 0, 1, alvo
IF alvo > 0
SET_CHAR_OBJ_AIM_GUN_AT_CHAR scplayer2 alvo
WHILE IS_KEY_PRESSED VK_KEY_Y
IF IS_KEY_PRESSED VK_KEY_U //tecla de trocar de alvo (semelhante aos R2/L2)
GET_RANDOM_CHAR_IN_SPHERE_NO_SAVE_RECURSIVE x, y, z, 20.0, 1, 1, alvo
IF alvo > 0
SET_CHAR_OBJ_AIM_GUN_AT_CHAR scplayer2 alvo
ENDIF
WHILE IS_KEY_PRESSED VK_KEY_U
WAIT 0
ENDWHILE
ENDIF
IF IS_KEY_PRESSED VK_KEY_H
IF alvo > 0
WHILE alvo > 0 // agora relendo o código, acho que nem era pra colocar um while dentro de um IF. Vou revisar depois
AND IS_KEY_PRESSED VK_KEY_H
SET_CHAR_OBJ_KILL_CHAR_ANY_MEANS scplayer2 alvo
WAIT 300
CHAR_SET_IDLE scplayer2
SET_CHAR_OBJ_AIM_GUN_AT_CHAR scplayer2 alvo
ENDWHILE
ENDIF
ENDIF
WAIT 0
ENDWHILE
CHAR_SET_IDLE scplayer2
ENDIF
ENDIF
RETURN
}
SCRIPT_END
//cleo_call camera_angle. É cleo_call porque as variáveis lx, ly, rx e ry só são usadas aqui e iriam "consumir" 4 slots de variável
{
LVAR_FLOAT c_angle //ângulo da câmera
LVAR_INT lx ly rx ry //posição dos analógicos
camera_angle: // muda o ângulo da câmera a partir de "," , "." ou da posição dos analógicos
IF c_angle > 360.0 //evita que valores maiores que 360 (volta completa) sejam armazenados
c_angle = 0.0
ENDIF
GET_POSITION_OF_ANALOGUE_STICKS 0, lx, ly, rx, ry
IF IS_KEY_PRESSED VK_OEM_COMMA //gira em sentido anti-horário
OR rx > 20
c_angle -= 5.0
ENDIF
IF IS_KEY_PRESSED VK_OEM_PERIOD //gira em sentido horário
OR rx < -20
c_angle += 5.0
ENDIF
CLEO_RETURN 0 c_angle //retorna c_angle para c_angle do escopo principal. Usado no script da câmera e na movimentalçao do jogador 2
}MUITA coisa ainda precisa melhorar (tal qual eu utilizar uma função para verificar se o handle do scplayer é válido e aí sim retornar um bit positivo, em vez de gastar uma variável para saber se está rolando um jogo 2 players, no caso, p2stat)
Sim, muita coisa precisa melhorar e talvez eu não consiga fazer algo legal pelas limitações do CLEO, mas vou tentar. Sabe como uma formiga come um elefante? Comendo um pedacinho de cada vez. Se preciso for (e estiver dentro das minhas capacidades) irei estudar LUA ou mesmo C++ para modificar mais a fundo o jogo.
Forte abraço a todos!