Página 1 de 1

[VC] 2 player / 2 jogadores Coop

Enviado: 21 Mai 2021, 13:39
por tassioluis
Salve a todos novamente!

Sempre desejei jogar o Vice City com 2 jogadores. Mas já vi que essa vontade vai ficar pra uma outra vida.

Por ninguém ter criado um mod que permitisse isso, eu resolvi ir atrás e fazer algo dentro das minhas limitações. Assim nasceu esse post aqui: [VC] 2 player / 2 Jogadores / Coop v0.3 Alpha

Eu tentei implementar o mod de 2 jogadores utilizando CLEO (no começo com Sanny Builder, depois pra GTA3script e retornei pro Sanny porque algumas funções não estavam funcionando no GTA3script) e recentemente dei um pouco mais de atenção pra fazer a coisa funcionar, apesar de ter tomado um banho de água fria do Junior_Djjr dizendo que seria impossível de fazer algo assim somente utilizando CLEO.

Recebi ajuda do nadalao e até chegamos a trocar um pouco de conhecimento.

Contudo agora cheguei num ponto em que eu conserto algo e outra coisa para de funcionar. Já estou com a cabeça quente e sem qualquer vontade de prosseguir com o projeto. (apesar de funcionar em parte)

A quem quiser dar continuidade, deixo o código em Sanny Builder (sei que o Junior_Djjr não gosta e não recomenda, mas foi onde eu consegui ter algum progresso).

Sei que meu código não está otimizado, possui inúmeros defeitos mas pode conter alguma ideia (assim como já teve e o nadalao aproveitou) pra algum outro mod.

Um forte abraço a todos e greetings from vice city!

SpoilerAbrir

Código: Selecionar tudo

{$CLEO .cs}

//-------------MAIN---------------
0000: NOP

/*
Variáveis
0@ = x coordinate (player 1)
1@ = y coordinate (player 1)
2@ = z coordinate (player 1)

3@ = player 2 handle
4@ = player 2 z_angle / closest car handle / player 2 marker handle / distance between players
5@ = player 2 target handle

6@ = camera angle
7@ = temp angle

8@ = player2 marker

10@ = x coordinate (player 2)
11@ = y coordinate (player 2)
12@ = z coordinate (player 2)

13@ = test sphere

14@ = temp var
15@ = multiplayer status

*/

:STANDBY
0001: wait 0 ms
00D6: if
0AB0:   key_pressed 0x7A // F11 key
004D: jump_if_false @STANDBY
0002: jump @START

:START
0001: wait 0 ms
0007: 6@ = 0.0 // @ = float c_angle
0007: 7@ = 0.0 // @ = int
//0006: 5@ = -1 // @ = int
0006: 15@ = 0 // @ = int
0002: jump @ACTIVATE

:ACTIVATE
023C: load_special_actor 10 'IGKEN'
0247: request_model #python
0002: jump @LOAD

:LOAD
0001: wait 0 ms
00D6: if and
0248:   model #SPECIAL10 available
0248:   model #python available
004D: jump_if_false @LOAD
0002: jump @SPAWN

:SPAWN
04C4: create_coordinate 10@ 11@ 12@ from_actor $PLAYER_ACTOR offset 2.0 2.0 2.0
009A: 3@ = create_actor_pedtype 1 model #SPECIAL10 at 10@ 11@ 12@
009F: set_actor 3@ idle
0223: set_actor 3@ health_to 100
0568: set_actor 3@ untargetable 1
01B2: give_actor 3@ weapon 18 ammo 200 // Load the weapon model before using this
02A8: 8@ = create_marker 0 at 10@ 11@ 12@
0ACE: show_formatted_text_box "2 PLAYER ACTIVATED"
018C: play_sound 1 at 0@ 1@ 2@
0002: jump @RELEASEF11

:RELEASEF11
0001: wait 0 ms
00D6: if
0AB0:   key_pressed 0x7A // F11 key
004D: jump_if_false @MAIN
0002: jump @RELEASEF11



:MAIN //tem por objetivo ficar "ciclando" as tarefas
0001: wait 0 ms

:CHECK
00D6: if
0019:   3@ > 0 // integer values
004D: jump_if_false @RESTORE

0164: disable_marker 8@
00A0: store_actor 3@ position_to 10@ 11@ 12@
02A8: 8@ = create_marker 0 at 10@ 11@ 12@

00D6: if
00E0:   player $player_char in_any_car
004D: jump_if_false @FOOTCAMERA
015A: restore_camera
0002: jump @THREAD2


//------------[camera]-------------------------------
:FOOTCAMERA
0460: set_camera_pointing_time 0.0 100
00A0: store_actor $player_actor position_to 0@ 1@ 2@
00A0: store_actor 3@ position_to 10@ 11@ 12@
0509: 4@ = distance_between_point 0@ 1@ and_point 10@ 11@

000B: 10@ += 0@
000B: 11@ += 1@
000B: 12@ += 2@
0015: 10@ /= 2.0
0015: 11@ /= 2.0
0015: 12@ /= 2.0

02F7: 0@ = cosine 6@ // float
02F6: 1@ = sine 6@ // float
0069: 0@ *= 4@
0069: 1@ *= 4@
0009: 10@ += 0@
0009: 11@ += 1@

0011: 4@ *= 0.05 // $ *= float
0069: 12@ *= 4@
0009: 12@ += 10.0

015F: set_camera_position 10@ 11@ 12@ rotation 0.0 0.0 0.0


00A0: store_actor $player_actor position_to 0@ 1@ 2@
00A0: store_actor 3@ position_to 10@ 11@ 12@

000B: 10@ += 0@
000B: 11@ += 1@
000B: 12@ += 2@
0015: 10@ /= 2.0
0015: 11@ /= 2.0
0015: 12@ /= 2.0
0160: point_camera 10@ 11@ 12@ switchstyle 1
0001: wait 0 ms
0002: jump @THREAD1
//------------[camera]-------------------------------






:THREAD1
00D6: if or
0AB0:   key_pressed 0x49 // I key
0AB0:   key_pressed 0x4C // L key
0AB0:   key_pressed 0x4A // J key
0AB0:   key_pressed 0x4B // K key
004D: jump_if_false @THREAD2
0002: jump @WALK

:THREAD2
009F: set_actor 3@ idle
00D6: if
0AB0:   key_pressed 0x48 // H key
004D: jump_if_false @THREAD3
0002: jump @GETINCAR

:THREAD3
00D6: if
0AB0:   key_pressed 0x4F // O key
004D: jump_if_false @THREAD4
0002: jump @SHOOT

:THREAD4
00D6: if
0AB0:   key_pressed 0x65
004D: jump_if_false @THREAD5
0002: jump @CROUCH

:THREAD5
00D6: if or
0AB0:   key_pressed 0xBC // , key
0AB0:   key_pressed 0xBE // . key
004D: jump_if_false @THREAD6
0002: jump @TURNCAMERA

:THREAD6
00D6: if or
0112:   wasted_or_busted
0118:   actor 3@ dead
0AB0:   key_pressed 0x7A // F11 key
004D: jump_if_false @MAIN
0002: jump @RESTORE

//------------[thread 1]-------------------------------
:WALK
00D6: if
80DF:   not actor 3@ in_any_car
004D: jump_if_false @MAIN
0002: jump @DIRECTION

:DIRECTION
0007: 7@ = 0.0 // @ = float

:NE
00D6: if and
0AB0: key_pressed 0x49 // I key
0AB0: key_pressed 0x4C // L key
004D: jump_if_false @SE
0007: 7@ = 315.0 // @ = float
0002: jump @MOVE

:SE
00D6: if and
0AB0: key_pressed 0x4C // L key
0AB0: key_pressed 0x4B // K key
004D: jump_if_false @SW
0007: 7@ = 225.0 // @ = float
0002: jump @MOVE

:SW
00D6: if and
0AB0: key_pressed 0x4A // J key
0AB0: key_pressed 0x4B // K key
004D: jump_if_false @NW
0007: 7@ = 135.0 // @ = float
0002: jump @MOVE

:NW
00D6: if and
0AB0: key_pressed 0x49 // I key
0AB0: key_pressed 0x4A // J key
004D: jump_if_false @NORTH
0007: 7@ = 45.0 // @ = float
0002: jump @MOVE

:NORTH
00D6: if
0AB0: key_pressed 0x49 // I key
004D: jump_if_false @SOUTH
0007: 7@ = 0.0 // @ = float
0002: jump @MOVE

:SOUTH
00D6: if
0AB0: key_pressed 0x4B // K key
004D: jump_if_false @EAST
0007: 7@ = 180.0 // @ = float
0002: jump @MOVE

:EAST
00D6: if
0AB0: key_pressed 0x4C // L key
004D: jump_if_false @WEST
0007: 7@ = 270.0 // @ = float
0002: jump @MOVE

:WEST
00D6: if
0AB0: key_pressed 0x4A // J key
004D: jump_if_false @MOVE
0007: 7@ = 90.0 // @ = float
0002: jump @MOVE


:MOVE
04C4: create_coordinate 10@ 11@ 12@ from_actor 3@ offset 0.0 0.0 0.0

000B: 6@ += 7@ // @ += float

02F7: 0@ = cosine 6@ // float
02F6: 1@ = sine 6@ // float
000F: 10@ -= 0@ // @ -= float
000F: 11@ -= 1@ // @ -= float

000F: 6@ -= 7@ // @ -= float

0239: actor 3@ run_to 10@ 11@

0002: jump @MAIN
//------------[thread 1]-------------------------------





//------------[thread 2]-------------------------------
:GETINCAR
00D6: if
00DF:   actor 3@ in_any_car
004D: jump_if_false @GETIN
03E2: actor 3@ leave_any_car
0002: jump @THREAD3

:GETIN
04C4: create_coordinate 10@ 11@ 12@ from_actor 3@ offset 0.0 0.0 0.0
0AE2: 4@ = random_vehicle_near_point 10@ 11@ 12@ in_radius 10.0 find_next 0 pass_wrecked 0
0019:   4@ > 0 // integer values
004D: jump_if_false @MAIN
01D4: actor 3@ go_to_car 4@ and_enter_it_as_a_passenger
0002: jump @THREAD3
//------------[thread 2]-------------------------------





//------------[thread 3]-------------------------------
:SHOOT

04C4: create_coordinate 10@ 11@ 12@ from_actor 3@ offset 0.0 0.0 0.0
0172: 4@ = actor 3@ z_angle
000B: 4@ += 75.0 // offset angle value (front of player2)
02F7: 0@ = cosine 4@ // decomposing arrays x and y
02F6: 1@ = sine 4@ // float
0011: 0@ *= 6.0 // $ *= float
0011: 1@ *= 6.0 // $ *= float
000B: 10@ += 0@ // @ -= float
000B: 11@ += 1@ // @ -= float

//03BC: 13@ = create_sphere 10@ 11@ 12@ 15.0
//0001: wait 500 ms
//03BD: destroy_sphere 13@

:FINDTARGET
0001: wait 0 ms

00D6: if
0AB0:   key_pressed 0x4F // O key
004D: jump_if_false @MAIN

0AE1: 5@ = random_actor_near_point 10@ 11@ 12@ in_radius 15.0 find_next 0 pass_deads 1
00D6: if
0019:   5@ > 0 // integer values
004D: jump_if_false @FINDTARGET


:KILL
00D6: if
0039:   3@ == 5@ // @ == int
004D: jump_if_false @SHOOTTOKILL
0002: jump @NEXTTARGET

:SHOOTTOKILL
//0321: kill_actor 5@
04C6: actor 3@ aim_gun_at_actor 5@
//01C9: actor 3@ kill_actor 5@
0001: wait 500 ms
009F: set_actor 3@ idle
0002: jump @MAIN

:NEXTTARGET
0001: wait 0 ms

00D6: if
0AB0:   key_pressed 0x4F // O key
004D: jump_if_false @MAIN

0AE1: 5@ = random_actor_near_point 0@ 1@ 2@ in_radius 15.0 find_next 1 pass_deads 1
00D6: if
0019:   5@ > 0 // integer values
004D: jump_if_false @NEXTTARGET
0002: jump @KILL
//------------[thread 3]-------------------------------






//------------[thread 4]-------------------------------
:CROUCH
04EB: actor 3@ crouch 1 50 ms
0002: jump @THREAD5
//------------[thread 4]-------------------------------




//------------[thread 5]-------------------------------
:TURNCAMERA

:LEFT
00D6: if
0AB0:   key_pressed 0xBE // . key
004D: jump_if_false @RIGHT
000B: 6@ += 5.0 // @ += float
0002: jump @THREAD6

:RIGHT
000F: 6@ -= 5.0 // @ -= float
0002: jump @THREAD6
//------------[thread 5]-------------------------------





//------------[thread 6]-------------------------------
:RESTORE
0164: disable_marker 8@
015A: restore_camera
0ACE: show_formatted_text_box "2 PLAYER DEACTIVATED"
018C: play_sound 1 at 0@ 1@ 2@
0006: 15@ = 0 // @ = int

:RELEASEF11AGAIN
0001: wait 0 ms
00D6: if
0AB0:   key_pressed 0x7A // F11 key
004D: jump_if_false @VANISHKEN
0002: jump @RELEASEF11AGAIN

:VANISHKEN
00D6: if
0019:   3@ > 0 // integer values
004D: jump_if_false @START
034F: destroy_actor_with_fade 3@ // The actor fades away like a ghost
01C2: mark_actor_as_no_longer_needed 3@
0249: release_model #SPECIAL10
0249: release_model #python
0001: wait 0 ms
0002: jump @START

Re: [VC] 2 player / 2 jogadores Coop

Enviado: 21 Mai 2021, 14:04
por Junior_Djjr
tassioluis escreveu:
21 Mai 2021, 13:39
A quem quiser dar continuidade, deixo o código em Sanny Builder (sei que o Junior_Djjr não gosta e não recomenda, mas foi onde eu consegui ter algum progresso).
Pior, você programou em low level, não é assim que se programa, isso é o código de como a máquina processa o script, não de como humanos criam o script.

Pra criar no Sanny Builder poderia ter aprendido com o tutorial do LINK/2012, mas não tem nenhum motivo mais.

E você viu este mod?
https://www.mixmods.com.br/2020/04/vc-v ... n-mod.html

Re: [VC] 2 player / 2 jogadores Coop

Enviado: 26 Mai 2021, 12:18
por tassioluis
Junior_Djjr escreveu:
21 Mai 2021, 14:04
tassioluis escreveu:
21 Mai 2021, 13:39
A quem quiser dar continuidade, deixo o código em Sanny Builder (sei que o Junior_Djjr não gosta e não recomenda, mas foi onde eu consegui ter algum progresso).
Pior, você programou em low level, não é assim que se programa, isso é o código de como a máquina processa o script, não de como humanos criam o script.

Pra criar no Sanny Builder poderia ter aprendido com o tutorial do LINK/2012, mas não tem nenhum motivo mais.

E você viu este mod?
https://www.mixmods.com.br/2020/04/vc-v ... n-mod.html  
Vi sim o mod. E o pelo autor original ter abandonado o mod e não ter liberado o código-fonte dele pra caso alguém tivesse interesse em dar prosseguimento, resolvi fazer alguma coisa pra jogar em co-op.

Se eu me animar de novo, volto a tentar algo com esse mod, mas dessa vez em GTA3script.

Até tinha feito um port, mas é de uma versão mais antiga e com uma outra abordagem em alguns aspectos. Lembrando que estava igualmente interminado. Segue abaixo:

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 p2stat     //status do jogo 2 player
LVAR_INT lx ly rx ry    //posição dos analógicos


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
        GOSUB camera_angle
        GOSUB morto
        GOSUB display
        //GOSUB carro 
    ENDIF

GOTO inicio

start2p:
    IF p2stat = 0
        SET_INTERPOLATION_PARAMETERS 0.0 100 //isso é para a câmera não ficar pulando
        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
        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  //frente
            GET_CHAR_COORDINATES scplayer2, x, y, z     //movimentação relativa à câmera. 
            COS c_angle, a                              //Também trigonometria básica. 
            SIN c_angle, b                              //Se usa o ângulo da câmera para decompor as resultantes x e y
            a *= 1.0                                    //e aplica os valores relativos à câmera às coordenadas do mundo.
            b *= 1.0
            x -= a
            y -= b
            SET_CHAR_OBJ_SPRINT_TO_COORD scplayer2 x, y
        ENDIF

        IF IS_KEY_PRESSED VK_KEY_J  //esquerda
            GET_CHAR_COORDINATES scplayer2, x, y, z
            SIN c_angle, a      //para os lados, deve-se inverter os coeficientes (seno e cosseno) de x com y (neste caso, a com b)
            COS c_angle, b      //tecnicamente, o que queremos é a perpendicular a esta reta
            a *= 1.0
            b *= 1.0
            x += a      
            y -= b              //e para isso, além do anteriores, temos que inverter esse valor (para ir para a esquerda)
            SET_CHAR_OBJ_SPRINT_TO_COORD scplayer2 x, y
        ENDIF

        IF IS_KEY_PRESSED VK_KEY_L  //direita
            GET_CHAR_COORDINATES scplayer2, x, y, z
            SIN c_angle, a
            COS c_angle, b
            a *= 1.0
            b *= 1.0
            x -= a              //e esse aqui para ir para a direita
            y += b
            SET_CHAR_OBJ_SPRINT_TO_COORD scplayer2 x, y
        ENDIF

        IF IS_KEY_PRESSED VK_KEY_K  //trás
            GET_CHAR_COORDINATES scplayer2, x, y, z
            COS c_angle, a
            SIN c_angle, b
            a *= 1.0
            b *= 1.0
            x += a
            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
    x += a
    y += b
    x /= 2.0
    y /= 2.0
    POINT_CAMERA_AT_POINT x, y, z, 1

    // aqui, é para definir o raio da câmera, bem como sua posição
    COS c_angle, a
    SIN c_angle, b
    a *= dist
    b *= dist
    x += a
    y += b
    dist *= 0.05
    z *= dist
    z += 12.0

    SET_FIXED_CAMERA_POSITION x, y, z, 0.0, 0.0, 0.0
RETURN

camera_angle:   // muda o ângulo da câmera a partir de "," , "." ou da posição dos analógicos

    IF c_angle > 360.0
        c_angle = 0.0
    ENDIF

    GET_POSITION_OF_ANALOGUE_STICKS 0, lx, ly, rx, ry

    IF IS_KEY_PRESSED VK_OEM_COMMA
    OR rx > 20
        c_angle -= 5.0
    ENDIF

    IF IS_KEY_PRESSED VK_OEM_PERIOD
    OR rx < -20
        c_angle += 5.0
    ENDIF

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




display:

    GET_CHAR_HEALTH scplayer2 ry
    PRINT_FORMATTED "Saude do Player 2: %.0f" 100 ry

RETURN

}
SCRIPT_END

Re: [VC] 2 player / 2 jogadores Coop

Enviado: 25 Nov 2021, 12:19
por tassioluis
Junior_Djjr escreveu:
21 Mai 2021, 14:04
tassioluis escreveu:
21 Mai 2021, 13:39
A quem quiser dar continuidade, deixo o código em Sanny Builder (sei que o Junior_Djjr não gosta e não recomenda, mas foi onde eu consegui ter algum progresso).
Pior, você programou em low level, não é assim que se programa, isso é o código de como a máquina processa o script, não de como humanos criam o script.

Pra criar no Sanny Builder poderia ter aprendido com o tutorial do LINK/2012, mas não tem nenhum motivo mais.

E você viu este mod?
https://www.mixmods.com.br/2020/04/vc-v ... n-mod.html 
Fala Juninho!

Saiu uma atualização do mod. Tá escrito todo em GTA3Script e deu uma melhorada substancial.

Dá uma olhada!

 [VC] 2 players / 2 jogadores Coop v0.4

Forte abraço!