Adding hightlight to player names when they follow each others

This commit is contained in:
David Négrier 2021-12-23 18:07:51 +01:00
parent 368a115b4c
commit 524339a3a0
5 changed files with 132 additions and 27 deletions

View file

@ -72,9 +72,7 @@ vim: ft=typescript
function reset() {
gameScene.connection?.emitFollowAbort();
followStateStore.set(followStates.off);
followRoleStore.set(followRoles.leader);
followUsersStore.set([]);
followUsersStore.stopFollowing();
}
function request() {

View file

@ -271,28 +271,17 @@ export class RoomConnection implements RoomConnection {
} else if (message.hasFollowrequestmessage()) {
const requestMessage = message.getFollowrequestmessage() as FollowRequestMessage;
if (!localUserStore.getIgnoreFollowRequests()) {
followStateStore.set(followStates.requesting);
followRoleStore.set(followRoles.follower);
followUsersStore.set([requestMessage.getLeader()]);
followUsersStore.addFollowRequest(requestMessage.getLeader());
}
} else if (message.hasFollowconfirmationmessage()) {
const responseMessage = message.getFollowconfirmationmessage() as FollowConfirmationMessage;
followUsersStore.set([...get(followUsersStore), responseMessage.getFollower()]);
followUsersStore.addFollower(responseMessage.getFollower());
} else if (message.hasFollowabortmessage()) {
const abortMessage = message.getFollowabortmessage() as FollowAbortMessage;
if (get(followRoleStore) === followRoles.follower) {
followStateStore.set(followStates.off);
followRoleStore.set(followRoles.leader);
followUsersStore.set([]);
followUsersStore.stopFollowing();
} else {
let followers = get(followUsersStore);
const oldFollowerCount = followers.length;
followers = followers.filter((name) => name !== abortMessage.getFollower());
followUsersStore.set(followers);
if (followers.length === 0 && oldFollowerCount > 0) {
followStateStore.set(followStates.off);
followRoleStore.set(followRoles.leader);
}
followUsersStore.removeFollower(abortMessage.getFollower());
}
} else if (message.hasErrormessage()) {
const errorMessage = message.getErrormessage() as ErrorMessage;

View file

@ -1,7 +1,7 @@
import type { Subscription } from "rxjs";
import AnimatedTiles from "phaser-animated-tiles";
import { Queue } from "queue-typescript";
import { get } from "svelte/store";
import { get, Unsubscriber } from "svelte/store";
import { userMessageManager } from "../../Administration/UserMessageManager";
import { connectionManager } from "../../Connexion/ConnectionManager";
@ -91,6 +91,8 @@ import { deepCopy } from "deep-copy-ts";
import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR;
import { MapStore } from "../../Stores/Utils/MapStore";
import { SetPlayerDetailsMessage } from "../../Messages/generated/messages_pb";
import { followUsersColorStore, followUsersStore } from "../../Stores/FollowStore";
import { getColorRgbFromHue } from "../../WebRtc/ColorGenerator";
export interface GameSceneInitInterface {
initPosition: PointInterface | null;
@ -165,9 +167,11 @@ export class GameScene extends DirtyScene {
private createPromise: Promise<void>;
private createPromiseResolve!: (value?: void | PromiseLike<void>) => void;
private iframeSubscriptionList!: Array<Subscription>;
private peerStoreUnsubscribe!: () => void;
private emoteUnsubscribe!: () => void;
private emoteMenuUnsubscribe!: () => void;
private peerStoreUnsubscribe!: Unsubscriber;
private emoteUnsubscribe!: Unsubscriber;
private emoteMenuUnsubscribe!: Unsubscriber;
private followUsersColorStoreUnsubscribe!: Unsubscriber;
private biggestAvailableAreaStoreUnsubscribe!: () => void;
MapUrlFile: string;
roomUrl: string;
@ -646,6 +650,16 @@ export class GameScene extends DirtyScene {
}
});
this.followUsersColorStoreUnsubscribe = followUsersColorStore.subscribe((color) => {
if (color !== undefined) {
this.CurrentPlayer.setOutlineColor(color);
this.connection?.emitPlayerOutlineColor(color);
} else {
this.CurrentPlayer.removeOutlineColor();
this.connection?.emitPlayerOutlineColor(null);
}
});
Promise.all([this.connectionAnswerPromise as Promise<unknown>, ...scriptPromises]).then(() => {
this.scene.wake();
});
@ -1443,6 +1457,7 @@ ${escapedMessage}
this.peerStoreUnsubscribe();
this.emoteUnsubscribe();
this.emoteMenuUnsubscribe();
this.followUsersColorStoreUnsubscribe();
this.biggestAvailableAreaStoreUnsubscribe();
iframeListener.unregisterAnswerer("getState");
iframeListener.unregisterAnswerer("loadTileset");

View file

@ -1,4 +1,6 @@
import { writable } from "svelte/store";
import { derived, writable } from "svelte/store";
import { getColorRgbFromHue } from "../WebRtc/ColorGenerator";
import { gameManager } from "../Phaser/Game/GameManager";
export const followStates = {
off: "off",
@ -14,4 +16,85 @@ export const followRoles = {
export const followStateStore = writable(followStates.off);
export const followRoleStore = writable(followRoles.leader);
export const followUsersStore = writable<number[]>([]);
//export const followUsersStore = writable<number[]>([]);
function createFollowUsersStore() {
const { subscribe, update, set } = writable<number[]>([]);
return {
subscribe,
addFollowRequest(leader: number): void {
followStateStore.set(followStates.requesting);
followRoleStore.set(followRoles.follower);
set([leader]);
},
addFollower(user: number): void {
update((followers) => {
followers.push(user);
return followers;
});
},
/**
* Removes the follower from the store.
* Will update followStateStore and followRoleStore if nobody is following anymore.
* @param user
*/
removeFollower(user: number): void {
update((followers) => {
const oldFollowerCount = followers.length;
followers = followers.filter((id) => id !== user);
if (followers.length === 0 && oldFollowerCount > 0) {
followStateStore.set(followStates.off);
followRoleStore.set(followRoles.leader);
}
return followers;
});
},
stopFollowing(): void {
set([]);
followStateStore.set(followStates.off);
followRoleStore.set(followRoles.leader);
},
};
}
export const followUsersStore = createFollowUsersStore();
/**
* This store contains the color of the follow group. It is derived from the ID of the leader.
*/
export const followUsersColorStore = derived(
[followStateStore, followRoleStore, followUsersStore],
([$followStateStore, $followRoleStore, $followUsersStore]) => {
console.log($followStateStore);
if ($followStateStore !== followStates.active) {
return undefined;
}
if ($followUsersStore.length === 0) {
return undefined;
}
let leaderId: number;
if ($followRoleStore === followRoles.leader) {
// Let's get my ID by a quite complicated way....
leaderId = gameManager.getCurrentGameScene().connection?.getUserId() ?? 0;
} else {
leaderId = $followUsersStore[0];
}
// Let's compute a random hue between 0 and 1 that varies enough to be interesting
const hue = ((leaderId * 197) % 255) / 255;
let { r, g, b } = getColorRgbFromHue(hue);
if ($followRoleStore === followRoles.follower) {
// Let's make the followers very slightly darker
r *= 0.9;
g *= 0.9;
b *= 0.9;
}
return (Math.round(r * 255) << 16) | (Math.round(g * 255) << 8) | Math.round(b * 255);
}
);

View file

@ -1,13 +1,29 @@
export function getRandomColor(): string {
const { r, g, b } = getColorRgbFromHue(Math.random());
return toHexa(r, g, b);
}
function toHexa(r: number, g: number, b: number): string {
return "#" + Math.floor(r * 256).toString(16) + Math.floor(g * 256).toString(16) + Math.floor(b * 256).toString(16);
}
export function getColorRgbFromHue(hue: number): { r: number; g: number; b: number } {
const golden_ratio_conjugate = 0.618033988749895;
let hue = Math.random();
hue += golden_ratio_conjugate;
hue %= 1;
return hsv_to_rgb(hue, 0.5, 0.95);
}
function stringToDouble(string: string): number {
let num = 1;
for (const char of string.split("")) {
num *= char.charCodeAt(0);
}
return (num % 255) / 255;
}
//todo: test this.
function hsv_to_rgb(hue: number, saturation: number, brightness: number): string {
function hsv_to_rgb(hue: number, saturation: number, brightness: number): { r: number; g: number; b: number } {
const h_i = Math.floor(hue * 6);
const f = hue * 6 - h_i;
const p = brightness * (1 - saturation);
@ -48,5 +64,9 @@ function hsv_to_rgb(hue: number, saturation: number, brightness: number): string
default:
throw "h_i cannot be " + h_i;
}
return "#" + Math.floor(r * 256).toString(16) + Math.floor(g * 256).toString(16) + Math.floor(b * 256).toString(16);
return {
r,
g,
b,
};
}