Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change Joints During the Game #2200

Open
vitormarchini opened this issue Oct 16, 2024 · 4 comments
Open

Change Joints During the Game #2200

vitormarchini opened this issue Oct 16, 2024 · 4 comments

Comments

@vitormarchini
Copy link

vitormarchini commented Oct 16, 2024

¹• I would like to know if it is possible to join, for example, disk 0 with disk 5 while the game is running.

²• Another thing. I know that it is not possible to join a disk to a player through HaxPuck. However, is it possible to do this through a script, since, as soon as the player enters the field, he becomes a disc? If it is possible, could you explain to me the correct method to do this?

³• Is it possible change cMask, cGroup and trait of discs while the game is running?

NOTE: I am a map creator, I understand the bare minimum of javascript, but to create BOTs, I only use ChatGPT, I'm sorry for my ignorance.

@alpheratz0
Copy link

¹• I would like to know if it is possible to join, for example, disk 0 with disk 5 while the game is running.

Hi! You can't join them directly, but you can move discs. For example, you could move discs 6 and 7 (connected by a joint) to where discs 0 and 5 are, and then move 0 and 5 off the screen.

²• Another thing. I know that it is not possible to join a disk to a player through HaxPuck. However, is it possible to do this through a script, since, as soon as the player enters the field, he becomes a disc? If it is possible, could you explain to me the correct method to do this?

Currently, the API doesn’t support that. However, there are some tricks that can get you close to what you want, though they aren’t perfect. One approach is to wrap the player in a box made of joints. You could then programmatically move the box around the player (just once) as needed.

³• Is it possible change cMask, cGroup <...> of discs while the game is running

You can, see setDiscProperties, getDiscProperties, setPlayerDiscProperties and getPlayerDiscProperties.

You may also want to check the CollisionFlags page.

const { CollisionFlags } = room;
room.setDiscProperties(0 /* disc index, 0 = ball disc, 1 = 1st stadium disc, 2 = 2nd stadium disc... */, {
	cGroup: CollisionFlags.all, // in stadium files this is the same as ["all"]
	cMask: CollisionFlags.red | CollisionFlags.blue // in stadium files this is the same as ["red", "blue"]
})

... and trait of discs while the game is running?

No, once the stadium is parsed and loaded, traits are gone. Traits are only useful for map editors.

@vitormarchini
Copy link
Author

vitormarchini commented Oct 21, 2024

Thank you so much, @alpheratz0

About moving the discs around the player, I coincidentally did something similar a few years ago, but only for maps, I hadn't started using BOTs. However, through scripting, I'm facing another problem that you would probably understand and I would like you to help me, if possible, through Discord when you have time so I can show you in real time what happens.

About cGroup and cMask, I still haven't been able to fix them to change them during the game. I'm also having problems with bCoef, which, when I use a command to change the bCoef of a disc during the game, nothing happens.

Right now, the commands is working (wrongly) like that:

    case 'bCoef':
        if (!isNaN(value[0])) {
            room.setDiscProperties(index, { bCoef: value[0] });
            room.sendAnnouncement(`Disco ${index} coeficiente de quique alterado para ${value[0]}`, playerId);
        } else {
            room.sendAnnouncement("Valor de bCoef inválido!", playerId, 0xFF0000);
        }
        break;
        
    case 'cMask':
        room.setDiscProperties(index, { cMask: args.slice(2) }); // Máscara de colisão como string
        room.sendAnnouncement(`Disco ${index} máscara de colisão alterada`, playerId);
        break;
        
    case 'cGroup':
        room.setDiscProperties(index, { cGroup: args.slice(2) }); // Grupo de colisão como string
        room.sendAnnouncement(`Disco ${index} grupo de colisão alterado`, playerId);
        break;

Could you call me on Discord so we can briefly discuss these details?

My Discord:
vitaohr.

@vitormarchini
Copy link
Author

@alpheratz0

@alpheratz0
Copy link

About moving the discs around the player, I coincidentally did something similar a few years ago, but only for maps, I hadn't started using BOTs. However, through scripting, I'm facing another problem that you would probably understand and I would like you to help me, if possible, through Discord when you have time so I can show you in real time what happens.

It would be a lot better for me if you could share it here, just record the screen and send the video with an explanation.
I'm busy

About cGroup and cMask, I still haven't been able to fix them to change them during the game. I'm also having problems with bCoef, which, when I use a command to change the bCoef of a disc during the game, nothing happens.

I see the problems.

First, it should be bCoeff (see https://github.com/haxball/haxball-issues/wiki/Headless-Host#bcoeff--float), yeah surely it didn't help that they have two different names, one for the stadiums and one in the headless API.

Second, cMask and cGroup should be provided in numerical form, you need to check the CollisionFlags (https://github.com/haxball/haxball-issues/wiki/Headless-Host#collisionflagsobject) object.

I fixed the problems and here is a working example of a room with the commands you want

const room = HBInit({
	public: false,
	noPlayer: true
})

room.onPlayerJoin = (player) => {
	room.setPlayerAdmin(player.id, true);
}

room.onPlayerChat = (player, message) => {
	if (message[0] != '!') return true;

	const args = message.split(' ');
	const command = args.shift().substr(1).toLowerCase();

	if (command == 'bcoef' && args.length == 2) {
		const [discId, bCoef] = args;
		room.setDiscProperties(parseInt(discId), {bCoeff: bCoef})
		room.sendAnnouncement(`Disco ${discId} coeficiente de quique alterado para ${bCoef}`, player.id);
	} else if ((command == 'cmask' || command == 'cgroup') && args.length > 1) {
		const [discId, ...cflagsStrArr] = args;
		// convert string-form collision flags into numerical forms
		const cflagsArr = cflagsStrArr.map(cflag => Object.hasOwn(room.CollisionFlags, cflag) ? room.CollisionFlags[cflag] : 0);
		// flag1 | flag2 | ... | flagN
		const cflags = cflagsArr.reduce((pVal, cVal) => pVal | cVal, 0);
		const discProps = command == 'cmask' ? {cMask: cflags} : {cGroup: cflags};
		room.setDiscProperties(parseInt(discId), discProps)
		const whatHasBeenUpdated = command == 'cmask' ? 'máscara de colisão' : 'grupo de colisão';
		room.sendAnnouncement(`Disco ${discId} ${whatHasBeenUpdated} alterada: ${cflags}`, player.id);
	} else {
		room.sendAnnouncement("Invalid command!", player.id);
	}

	return false;
}

Some commands you can run

// change collision mask of the third disc (top left post)
!cmask 3 blue
// change collision mask of the third disc (bottom left post)
!cmask 4 blue
// change bouncing coefficient of the ball
!bcoef 0 10
// change collision group of the top left post
!cgroup 3 red blue redKO blueKO ball

etc...

See

out.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants