forked from public/foundryvtt-reve-de-dragon
Big WIP...
This commit is contained in:
121
module/actor.js
121
module/actor.js
@ -212,7 +212,7 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
isHautRevant() {
|
||||
return this.isPersonnage() && this.attributs.hautrevant.value != ""
|
||||
return this.isPersonnage() && this.system.attributs.hautrevant.value != ""
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getFatigueActuelle() {
|
||||
@ -249,7 +249,7 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getAgilite() {
|
||||
switch (this.data.type) {
|
||||
switch (this.type) {
|
||||
case 'personnage': return Misc.toInt(this.system.carac.agilite?.value);
|
||||
case 'creature': return Misc.toInt(this.system.carac.force?.value);
|
||||
case 'entite': return Misc.toInt(this.system.carac.reve?.value);
|
||||
@ -422,7 +422,7 @@ export class RdDActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
getSurprise(isCombat = undefined) {
|
||||
let niveauSurprise = this.getActiveEffects()
|
||||
.map(effect => StatusEffects.valeurSurprise(effect.data, isCombat))
|
||||
.map(effect => StatusEffects.valeurSurprise(effect, isCombat))
|
||||
.reduce(Misc.sum(), 0);
|
||||
if (niveauSurprise > 1) {
|
||||
return 'totale';
|
||||
@ -787,7 +787,7 @@ export class RdDActor extends Actor {
|
||||
forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: this.getReveActuel() } }
|
||||
}
|
||||
rollData.rencontre.force = force;
|
||||
rollData.competence.data.defaut_carac = 'reve-actuel';
|
||||
rollData.competence.system.defaut_carac = 'reve-actuel';
|
||||
|
||||
const dialog = await RdDRoll.create(this, rollData,
|
||||
{
|
||||
@ -1150,8 +1150,8 @@ export class RdDActor extends Actor {
|
||||
async ajouterDansConteneur(item, conteneur, onAjouterDansConteneur) {
|
||||
if (conteneur?.isConteneur()) {
|
||||
let data2use = duplicate(conteneur);
|
||||
data2use.data.contenu.push(item.id);
|
||||
item.data.estContenu = true;
|
||||
data2use.system.contenu.push(item.id);
|
||||
item.system.estContenu = true;
|
||||
await this.updateEmbeddedDocuments('Item', [data2use]);
|
||||
onAjouterDansConteneur(item.id, conteneur.id);
|
||||
}
|
||||
@ -1422,8 +1422,8 @@ export class RdDActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async ajouterSouffle(options = { chat: false }) {
|
||||
let souffle = await RdDRollTables.getSouffle();
|
||||
souffle._id = undefined; //TBC
|
||||
let souffle = await RdDRollTables.getSouffle()
|
||||
//souffle.id = undefined; //TBC
|
||||
await this.createEmbeddedDocuments('Item', [souffle]);
|
||||
if (options.chat) {
|
||||
ChatMessage.create({
|
||||
@ -1471,7 +1471,7 @@ export class RdDActor extends Actor {
|
||||
game.socket.emit(SYSTEM_SOCKET_ID, {
|
||||
msg: "msg_tmr_move", data: {
|
||||
actorId: this._id,
|
||||
tmrPos: this.system.data.reve.tmrpos
|
||||
tmrPos: this.system.reve.tmrpos
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1504,7 +1504,7 @@ export class RdDActor extends Actor {
|
||||
buildTMRInnaccessible() {
|
||||
const tmrInnaccessibles = this.filterItemsData(it => Draconique.isCaseTMR(it) &&
|
||||
EffetsDraconiques.isInnaccessible(it));
|
||||
return tmrInnaccessibles.map(it => it.data.coord);
|
||||
return tmrInnaccessibles.map(it => it.system.coord);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -1582,13 +1582,13 @@ export class RdDActor extends Actor {
|
||||
async finDeRound(options = { terminer: false }) {
|
||||
for (let effect of this.getActiveEffects()) {
|
||||
if (effect.duration.type !== 'none' && (effect.duration.remaining <= 0 || options.terminer)) {
|
||||
if (effect.data.origin) {
|
||||
if (effect.system.origin) {
|
||||
await effect.update({ 'disabled': true });
|
||||
}
|
||||
else {
|
||||
await effect.delete();
|
||||
}
|
||||
ChatMessage.create({ content: `${this.name} n'est plus ${Misc.lowerFirst(game.i18n.localize(effect.data.label))} !` });
|
||||
ChatMessage.create({ content: `${this.name} n'est plus ${Misc.lowerFirst(game.i18n.localize(effect.system.label))} !` });
|
||||
}
|
||||
}
|
||||
if (this.type == 'personnage') {
|
||||
@ -2255,13 +2255,13 @@ export class RdDActor extends Actor {
|
||||
let letfilteredList = []
|
||||
for (let sort of sortList) {
|
||||
//console.log(sort.name, sort.data.caseTMR.toLowerCase(), sort.data.caseTMRspeciale.toLowerCase(), coord.toLowerCase() );
|
||||
if (sort.data.caseTMR.toLowerCase().includes('variable')) {
|
||||
if (sort.system.caseTMR.toLowerCase().includes('variable')) {
|
||||
letfilteredList.push(sort);
|
||||
} else if (sort.data.caseTMRspeciale.toLowerCase().includes('variable')) {
|
||||
} else if (sort.system.caseTMRspeciale.toLowerCase().includes('variable')) {
|
||||
letfilteredList.push(sort);
|
||||
} else if (sort.data.caseTMR.toLowerCase() == tmr.type) {
|
||||
} else if (sort.system.caseTMR.toLowerCase() == tmr.type) {
|
||||
letfilteredList.push(sort);
|
||||
} else if (sort.data.caseTMR.toLowerCase().includes('special') && sort.data.caseTMRspeciale.toLowerCase().includes(coord.toLowerCase())) {
|
||||
} else if (sort.system.caseTMR.toLowerCase().includes('special') && sort.system.caseTMRspeciale.toLowerCase().includes(coord.toLowerCase())) {
|
||||
letfilteredList.push(sort);
|
||||
}
|
||||
}
|
||||
@ -2274,7 +2274,7 @@ export class RdDActor extends Actor {
|
||||
let draconicList = this.getDraconicList()
|
||||
.map(it => {
|
||||
it = duplicate(it)
|
||||
it.data.defaut_carac = "reve";
|
||||
it.system.defaut_carac = "reve";
|
||||
return it;
|
||||
});
|
||||
for (let sort of sortList) {
|
||||
@ -2298,7 +2298,7 @@ export class RdDActor extends Actor {
|
||||
case "annulation de magie":
|
||||
return draconicList.filter(it => !Grammar.toLowerCaseNoAccent(it.name).includes('thanatos'));
|
||||
}
|
||||
return [RdDItemCompetence.getVoieDraconic(draconicList, sort.data.draconic)];
|
||||
return [RdDItemCompetence.getVoieDraconic(draconicList, sort.system.draconic)];
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -2385,7 +2385,7 @@ export class RdDActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async checkSoufflePeage(tmr) {
|
||||
if ((tmr.type == 'pont' || tmr.type == 'cite') && EffetsDraconiques.isPeage(actor)) {
|
||||
if ((tmr.type == 'pont' || tmr.type == 'cite') && EffetsDraconiques.isPeage(this)) {
|
||||
await this.reveActuelIncDec(-1);
|
||||
ChatMessage.create({
|
||||
content: "Vous êtes sous le coup d'un Péage : l'entrée sur cette case vous a coûté 1 Point de Rêve (déduit automatiquement).",
|
||||
@ -2399,9 +2399,9 @@ export class RdDActor extends Actor {
|
||||
let rolled = rollData.rolled;
|
||||
let selectedSort = rollData.selectedSort;
|
||||
|
||||
rollData.isSortReserve = rollData.mettreEnReserve && !selectedSort.data.isrituel;
|
||||
rollData.isSortReserve = rollData.mettreEnReserve && !selectedSort.system.isrituel;
|
||||
rollData.show = {}
|
||||
rollData.depenseReve = Number(selectedSort.data.ptreve_reel);
|
||||
rollData.depenseReve = Number(selectedSort.system.ptreve_reel);
|
||||
|
||||
if (rollData.competence.name.includes('Thanatos')) { // Si Thanatos
|
||||
await this.update({ "data.reve.reve.thanatosused": true });
|
||||
@ -2707,7 +2707,7 @@ export class RdDActor extends Actor {
|
||||
_getCaracDanse(oeuvre) {
|
||||
if (oeuvre.system.agilite) { return "agilite"; }
|
||||
else if (oeuvre.system.apparence) { return "apparence"; }
|
||||
const compData = this.getCompetence(oeuvre.data.competence);
|
||||
const compData = this.getCompetence(oeuvre.system.competence);
|
||||
return compData.system.defaut_carac;
|
||||
}
|
||||
|
||||
@ -2827,14 +2827,14 @@ export class RdDActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_meditationEPart(meditationRoll) {
|
||||
this.updateEmbeddedDocuments('Item', [{ _id: meditationRoll.meditation._id, 'data.malus': meditationRoll.meditation.data.malus - 1 }]);
|
||||
this.updateEmbeddedDocuments('Item', [{ _id: meditationRoll.meditation._id, 'data.malus': meditationRoll.meditation.system.malus - 1 }]);
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_getSignesDraconiques(coord) {
|
||||
const type = TMRUtility.getTMRType(coord);
|
||||
return this.listItemsData("signedraconique").filter(it => it.data.typesTMR.includes(type));
|
||||
return this.listItemsData("signedraconique").filter(it => it.system.typesTMR.includes(type));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -3063,7 +3063,7 @@ export class RdDActor extends Actor {
|
||||
await this.createEmbeddedDocuments("Item", [item]);
|
||||
|
||||
// Suppression des anciens nombres astraux
|
||||
let toDelete = this.listItemsData('nombreastral').filter(it => it.data.jourindex < game.system.rdd.calendrier.getCurrentDayIndex());
|
||||
let toDelete = this.listItemsData('nombreastral').filter(it => it.system.jourindex < game.system.rdd.calendrier.getCurrentDayIndex());
|
||||
const deletions = toDelete.map(it => it._id);
|
||||
await this.deleteEmbeddedDocuments("Item", deletions);
|
||||
|
||||
@ -3140,7 +3140,7 @@ export class RdDActor extends Actor {
|
||||
ui.notifications.warn("Vous êtes déja dans les TMR....");
|
||||
return
|
||||
}
|
||||
let demiReve = this.getActiveEffects(it => it.data.label == "Demi-rêve");
|
||||
let demiReve = this.getActiveEffects(it => it.label == "Demi-rêve");
|
||||
if (mode != 'visu' && demiReve.length > 0) {
|
||||
ui.notifications.warn("Le joueur ou le MJ est déja dans les Terres Médianes avec ce personnage ! Visualisation uniquement");
|
||||
mode = "visu"; // bascule le mode en visu automatiquement
|
||||
@ -3264,7 +3264,7 @@ export class RdDActor extends Actor {
|
||||
if (!ReglesOptionelles.isUsing('deteriorationArmure') || itemData.system.protection == '0') {
|
||||
return;
|
||||
}
|
||||
itemData.data.deterioration = (itemData.system.deterioration ?? 0) + dmg;
|
||||
itemData.system.deterioration = (itemData.system.deterioration ?? 0) + dmg;
|
||||
if (itemData.system.deterioration >= 10) {
|
||||
itemData.system.deterioration -= 10;
|
||||
let res = /(\d+)?d(\d+)(\-\d+)?/.exec(itemData.system.protection);
|
||||
@ -3380,14 +3380,14 @@ export class RdDActor extends Actor {
|
||||
let encaissement = RdDUtility.selectEncaissement(jetTotal, rollData.dmg.mortalite)
|
||||
let over20 = Math.max(jetTotal - 20, 0);
|
||||
encaissement.dmg = rollData.dmg;
|
||||
encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(this.data.type);
|
||||
encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(this.type);
|
||||
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;'
|
||||
encaissement.roll = roll;
|
||||
encaissement.armure = armure;
|
||||
encaissement.total = jetTotal;
|
||||
encaissement.vie = await RdDActor._evaluatePerte(encaissement.vie, over20);
|
||||
encaissement.endurance = await RdDActor._evaluatePerte(encaissement.endurance, over20);
|
||||
encaissement.penetration = rollData.arme?.data.penetration ?? 0;
|
||||
encaissement.penetration = rollData.arme?.system.penetration ?? 0;
|
||||
|
||||
return encaissement;
|
||||
}
|
||||
@ -3558,13 +3558,13 @@ export class RdDActor extends Actor {
|
||||
return;
|
||||
}
|
||||
resonnance.actors.push(attaquant._id);
|
||||
await this.update({ "data.sante.resonnance": resonnance });
|
||||
await this.update({ "system.sante.resonnance": resonnance });
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getFortune() {
|
||||
let monnaies = Monnaie.filtrerMonnaies(this.data.items);
|
||||
let monnaies = Monnaie.filtrerMonnaies(this.items);
|
||||
if (monnaies.length < 4) {
|
||||
ui.notifications.error("Problème de monnaies manquantes, impossible de payer correctement!")
|
||||
throw "Problème de monnaies manquantes, impossible de payer correctement!";
|
||||
@ -3576,7 +3576,7 @@ export class RdDActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async optimizeArgent(fortuneTotale) {
|
||||
let monnaies = Monnaie.filtrerMonnaies(this.data.items);
|
||||
let monnaies = Monnaie.filtrerMonnaies(this.items);
|
||||
let parValeur = Misc.classifyFirst(monnaies, it => this.system.valeur_deniers);
|
||||
let nouvelleFortune = {
|
||||
1000: Math.floor(fortuneTotale / 1000), // or
|
||||
@ -3600,8 +3600,8 @@ export class RdDActor extends Actor {
|
||||
let msg = "";
|
||||
if (depense == 0) {
|
||||
if (dataObj) {
|
||||
dataObj.payload.data.cout = depense / 100; // Mise à jour du prix en sols , avec le prix acheté
|
||||
dataObj.payload.data.quantite = quantite;
|
||||
dataObj.payload.system.cout = depense / 100; // Mise à jour du prix en sols , avec le prix acheté
|
||||
dataObj.payload.system.quantite = quantite;
|
||||
await this.createEmbeddedDocuments('Item', [dataObj.payload]);
|
||||
msg += `<br>L'objet <strong>${dataObj.payload.name}</strong> a été ajouté gratuitement à votre inventaire.`;
|
||||
}
|
||||
@ -3616,8 +3616,8 @@ export class RdDActor extends Actor {
|
||||
RdDAudio.PlayContextAudio("argent"); // Petit son
|
||||
|
||||
if (dataObj) {
|
||||
dataObj.payload.data.cout = depense / 100; // Mise à jour du prix en sols , avec le prix acheté
|
||||
dataObj.payload.data.quantite = quantite;
|
||||
dataObj.payload.system.cout = depense / 100; // Mise à jour du prix en sols , avec le prix acheté
|
||||
dataObj.payload.system.quantite = quantite;
|
||||
await this.createEmbeddedDocuments('Item', [dataObj.payload]);
|
||||
msg += `<br>Et l'objet <strong>${dataObj.payload.name}</strong> a été ajouté à votre inventaire.`;
|
||||
}
|
||||
@ -3814,7 +3814,7 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
|
||||
isCristalAlchimique(it) {
|
||||
return it.type == 'objet' && Grammar.toLowerCaseNoAccent(it.name) == 'cristal alchimique' && it.data.quantite > 0;
|
||||
return it.type == 'objet' && Grammar.toLowerCaseNoAccent(it.name) == 'cristal alchimique' && it.system.quantite > 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -3878,11 +3878,11 @@ export class RdDActor extends Actor {
|
||||
let subActor = game.actors.get(subActorId);
|
||||
//console.log("Ajout acteur : ", actor, this);
|
||||
if (subActor && !subActor.owner) {
|
||||
if (subActor.data.type == 'vehicule') {
|
||||
if (subActortype == 'vehicule') {
|
||||
this.pushSubacteur(subActor, this.system.subacteurs.vehicules, 'data.subacteurs.vehicules', 'Ce Véhicule');
|
||||
} else if (subActor.data.type == 'creature') {
|
||||
} else if (subActor.type == 'creature') {
|
||||
this.pushSubacteur(subActor, this.system.subacteurs.montures, 'data.subacteurs.montures', 'Cette Monture');
|
||||
} else if (subActor.data.type == 'personnage') {
|
||||
} else if (subActor.type == 'personnage') {
|
||||
this.pushSubacteur(subActor, this.system.subacteurs.suivants, 'data.subacteurs.suivants', 'Ce Suivant');
|
||||
}
|
||||
} else {
|
||||
@ -3946,17 +3946,17 @@ export class RdDActor extends Actor {
|
||||
potionData.alias = this.name;
|
||||
potionData.supprimer = true;
|
||||
|
||||
if (potionData.data.magique) {
|
||||
if (potionData.system.magique) {
|
||||
// Gestion de la résistance:
|
||||
potionData.rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8);
|
||||
if (potionData.rolled.isEchec) {
|
||||
await this.reveActuelIncDec(-1);
|
||||
potionData.guerisonData = await this.buildPotionGuerisonList(potionData.data.puissance);
|
||||
potionData.guerisonData = await this.buildPotionGuerisonList(potionData.system.puissance);
|
||||
potionData.guerisonMinutes = potionData.guerisonData.pointsConsommes * 5;
|
||||
}
|
||||
}
|
||||
if (!potionData.data.magique || potionData.rolled.isSuccess) {
|
||||
this.bonusRecuperationPotion = potionData.data.herbeBonus;
|
||||
if (!potionData.system.magique || potionData.rolled.isSuccess) {
|
||||
this.bonusRecuperationPotion = potionData.system.herbeBonus;
|
||||
}
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
|
||||
@ -3969,27 +3969,27 @@ export class RdDActor extends Actor {
|
||||
potionData.alias = this.name;
|
||||
potionData.supprimer = true;
|
||||
|
||||
if (potionData.data.magique) {
|
||||
if (potionData.system.magique) {
|
||||
// Gestion de la résistance:
|
||||
potionData.rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8);
|
||||
if (potionData.rolled.isEchec) {
|
||||
await this.reveActuelIncDec(-1);
|
||||
let fatigueActuelle = this.getFatigueActuelle();
|
||||
potionData.caseFatigueReel = Math.min(fatigueActuelle, potionData.data.puissance);
|
||||
potionData.guerisonDureeUnite = (potionData.data.reposalchimique) ? "rounds" : "minutes";
|
||||
potionData.guerisonDureeValue = (potionData.data.reposalchimique) ? potionData.caseFatigueReel : potionData.caseFatigueReel * 5;
|
||||
potionData.caseFatigueReel = Math.min(fatigueActuelle, potionData.system.puissance);
|
||||
potionData.guerisonDureeUnite = (potionData.system.reposalchimique) ? "rounds" : "minutes";
|
||||
potionData.guerisonDureeValue = (potionData.system.reposalchimique) ? potionData.caseFatigueReel : potionData.caseFatigueReel * 5;
|
||||
potionData.aphasiePermanente = false;
|
||||
if (potionData.data.reposalchimique) {
|
||||
if (potionData.system.reposalchimique) {
|
||||
let chanceAphasie = await RdDDice.rollTotal("1d100");
|
||||
if (chanceAphasie <= potionData.data.pr) {
|
||||
if (chanceAphasie <= potionData.system.pr) {
|
||||
potionData.aphasiePermanente = true;
|
||||
}
|
||||
}
|
||||
await this.santeIncDec("fatigue", -potionData.caseFatigueReel);
|
||||
}
|
||||
}
|
||||
if (!potionData.data.magique || potionData.rolled.isSuccess) {
|
||||
this.bonusRepos = potionData.data.herbeBonus;
|
||||
if (!potionData.system.magique || potionData.rolled.isSuccess) {
|
||||
this.bonusRepos = potionData.system.herbeBonus;
|
||||
}
|
||||
ChatMessage.create({
|
||||
whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name),
|
||||
@ -4006,20 +4006,20 @@ export class RdDActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
async fabriquerPotion(herbeData) {
|
||||
let newPotion = {
|
||||
name: `Potion de ${herbeData.data.categorie} (${herbeData.name})`, type: 'potion',
|
||||
name: `Potion de ${herbeData.system.categorie} (${herbeData.name})`, type: 'potion',
|
||||
img: "systems/foundryvtt-reve-de-dragon/icons/objets/fiole_verre.webp",
|
||||
data: {
|
||||
quantite: 1, valeur_deniers: 1, encombrement: 0.01,
|
||||
categorie: herbeData.data.categorie,
|
||||
categorie: herbeData.system.categorie,
|
||||
herbe: herbeData.name,
|
||||
rarete: herbeData.data.rarete,
|
||||
rarete: herbeData.system.rarete,
|
||||
herbebrins: herbeData.nbBrins,
|
||||
description: ""
|
||||
}
|
||||
}
|
||||
await this.createEmbeddedDocuments('Item', [newPotion], { renderSheet: true });
|
||||
|
||||
let newQuantite = herbeData.data.quantite - herbeData.nbBrins;
|
||||
let newQuantite = herbeData.system.quantite - herbeData.nbBrins;
|
||||
let messageData = {
|
||||
alias: this.name,
|
||||
nbBrinsReste: newQuantite,
|
||||
@ -4046,7 +4046,7 @@ export class RdDActor extends Actor {
|
||||
async consommerPotionGenerique(potionData) {
|
||||
potionData.alias = this.name;
|
||||
|
||||
if (potionData.data.magique) {
|
||||
if (potionData.system.magique) {
|
||||
// Gestion de la résistance:
|
||||
potionData.rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8);
|
||||
if (potionData.rolled.isEchec) {
|
||||
@ -4063,7 +4063,7 @@ export class RdDActor extends Actor {
|
||||
async consommerPotion(potion, onActionItem = async () => {}) {
|
||||
const potionData = potion
|
||||
|
||||
if (potionData.data.categorie.includes('Soin')) {
|
||||
if (potionData.system.categorie.includes('Soin')) {
|
||||
this.consommerPotionSoin(potionData);
|
||||
} else if (potionData.system.categorie.includes('Repos')) {
|
||||
this.consommerPotionRepos(potionData);
|
||||
@ -4096,8 +4096,9 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getEffectByLabel(label) {
|
||||
return this.getActiveEffects().find(it => it.data.label == label);
|
||||
getEffectByLabel(label) {
|
||||
console.log("Effects", this.getActiveEffects())
|
||||
return this.getActiveEffects().find(it => it.system?.label == label);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
Reference in New Issue
Block a user