feat(天赋系统): 实现天赋选择功能并完善卡片交互逻辑
添加天赋选择事件触发机制,在战斗开始时触发天赋选择界面 重构MissionCardComp类,实现天赋卡片的随机生成、显示和选择功能 为卡片添加选中状态标记和交互处理 更新prefab资源以支持新的天赋选择界面
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -38,19 +38,25 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__id__": 56
|
"__id__": 56
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 64
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_active": true,
|
"_active": true,
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 64
|
"__id__": 74
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__id__": 66
|
"__id__": 76
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 78
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_prefab": {
|
"_prefab": {
|
||||||
"__id__": 68
|
"__id__": 80
|
||||||
},
|
},
|
||||||
"_lpos": {
|
"_lpos": {
|
||||||
"__type__": "cc.Vec3",
|
"__type__": "cc.Vec3",
|
||||||
@@ -1492,6 +1498,234 @@
|
|||||||
"targetOverrides": null,
|
"targetOverrides": null,
|
||||||
"nestedPrefabInstanceRoots": null
|
"nestedPrefabInstanceRoots": null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "selected",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"_parent": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_children": [
|
||||||
|
{
|
||||||
|
"__id__": 65
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_active": true,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 71
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 73
|
||||||
|
},
|
||||||
|
"_lpos": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_lrot": {
|
||||||
|
"__type__": "cc.Quat",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"w": 1
|
||||||
|
},
|
||||||
|
"_lscale": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"z": 1
|
||||||
|
},
|
||||||
|
"_mobility": 0,
|
||||||
|
"_layer": 1073741824,
|
||||||
|
"_euler": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Node",
|
||||||
|
"_name": "GreenTick",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"_parent": {
|
||||||
|
"__id__": 64
|
||||||
|
},
|
||||||
|
"_children": [],
|
||||||
|
"_active": true,
|
||||||
|
"_components": [
|
||||||
|
{
|
||||||
|
"__id__": 66
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 68
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_prefab": {
|
||||||
|
"__id__": 70
|
||||||
|
},
|
||||||
|
"_lpos": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": -76.645,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_lrot": {
|
||||||
|
"__type__": "cc.Quat",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0,
|
||||||
|
"w": 1
|
||||||
|
},
|
||||||
|
"_lscale": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"z": 1
|
||||||
|
},
|
||||||
|
"_mobility": 0,
|
||||||
|
"_layer": 1073741824,
|
||||||
|
"_euler": {
|
||||||
|
"__type__": "cc.Vec3",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.UITransform",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 65
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 67
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 54,
|
||||||
|
"height": 54
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "f0xTeEhHVEmY81KJd5/ryK"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Sprite",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 65
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 69
|
||||||
|
},
|
||||||
|
"_customMaterial": null,
|
||||||
|
"_srcBlendFactor": 2,
|
||||||
|
"_dstBlendFactor": 4,
|
||||||
|
"_color": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 255,
|
||||||
|
"g": 255,
|
||||||
|
"b": 255,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_spriteFrame": {
|
||||||
|
"__uuid__": "deedea09-8f2b-400f-9803-4cfd38e45d1a@55373",
|
||||||
|
"__expectedType__": "cc.SpriteFrame"
|
||||||
|
},
|
||||||
|
"_type": 0,
|
||||||
|
"_fillType": 0,
|
||||||
|
"_sizeMode": 0,
|
||||||
|
"_fillCenter": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0
|
||||||
|
},
|
||||||
|
"_fillStart": 0,
|
||||||
|
"_fillRange": 0,
|
||||||
|
"_isTrimmedMode": true,
|
||||||
|
"_useGrayscale": false,
|
||||||
|
"_atlas": null,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "63qWzhuPFLV6vEcEmhLEAC"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__id__": 0
|
||||||
|
},
|
||||||
|
"fileId": "e8g5MwfEhD6Y0m0e23zag4",
|
||||||
|
"instance": null,
|
||||||
|
"targetOverrides": null,
|
||||||
|
"nestedPrefabInstanceRoots": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.UITransform",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 64
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 72
|
||||||
|
},
|
||||||
|
"_contentSize": {
|
||||||
|
"__type__": "cc.Size",
|
||||||
|
"width": 100,
|
||||||
|
"height": 100
|
||||||
|
},
|
||||||
|
"_anchorPoint": {
|
||||||
|
"__type__": "cc.Vec2",
|
||||||
|
"x": 0.5,
|
||||||
|
"y": 0.5
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "acA6HyWsxC3bepdLREshZ3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.PrefabInfo",
|
||||||
|
"root": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"asset": {
|
||||||
|
"__id__": 0
|
||||||
|
},
|
||||||
|
"fileId": "29hkGgh2lDpJ8GAA6r1xOh",
|
||||||
|
"instance": null,
|
||||||
|
"targetOverrides": null,
|
||||||
|
"nestedPrefabInstanceRoots": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.UITransform",
|
"__type__": "cc.UITransform",
|
||||||
"_name": "",
|
"_name": "",
|
||||||
@@ -1502,7 +1736,7 @@
|
|||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 65
|
"__id__": 75
|
||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
@@ -1530,7 +1764,7 @@
|
|||||||
},
|
},
|
||||||
"_enabled": false,
|
"_enabled": false,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 67
|
"__id__": 77
|
||||||
},
|
},
|
||||||
"_customMaterial": null,
|
"_customMaterial": null,
|
||||||
"_srcBlendFactor": 2,
|
"_srcBlendFactor": 2,
|
||||||
@@ -1565,6 +1799,62 @@
|
|||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
"fileId": "609hAwCWtPmqZXRsnP0C+8"
|
"fileId": "609hAwCWtPmqZXRsnP0C+8"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.Button",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 79
|
||||||
|
},
|
||||||
|
"clickEvents": [],
|
||||||
|
"_interactable": true,
|
||||||
|
"_transition": 3,
|
||||||
|
"_normalColor": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 255,
|
||||||
|
"g": 255,
|
||||||
|
"b": 255,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_hoverColor": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 211,
|
||||||
|
"g": 211,
|
||||||
|
"b": 211,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_pressedColor": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 255,
|
||||||
|
"g": 255,
|
||||||
|
"b": 255,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_disabledColor": {
|
||||||
|
"__type__": "cc.Color",
|
||||||
|
"r": 124,
|
||||||
|
"g": 124,
|
||||||
|
"b": 124,
|
||||||
|
"a": 255
|
||||||
|
},
|
||||||
|
"_normalSprite": null,
|
||||||
|
"_hoverSprite": null,
|
||||||
|
"_pressedSprite": null,
|
||||||
|
"_disabledSprite": null,
|
||||||
|
"_duration": 0.1,
|
||||||
|
"_zoomScale": 1.2,
|
||||||
|
"_target": null,
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "85rZYvTXxBq4pJCoHruVwe"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInfo",
|
"__type__": "cc.PrefabInfo",
|
||||||
"root": {
|
"root": {
|
||||||
|
|||||||
@@ -1,73 +1,169 @@
|
|||||||
import { _decorator, Label, Node } from "cc";
|
import { _decorator, Label, Node } from "cc";
|
||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||||
|
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||||
|
import { GameEvent } from "../common/config/GameEvent";
|
||||||
|
import { talConf, ItalConf } from "../common/config/TalSet";
|
||||||
|
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
/** 视图层对象 */
|
/** 视图层对象 */
|
||||||
@ccclass('ModuleViewComp')
|
@ccclass('MissionCardComp')
|
||||||
@ecs.register('ModuleView', false)
|
@ecs.register('MissionCard', false)
|
||||||
export class ModuleViewComp extends CCComp {
|
export class MissionCardComp extends CCComp {
|
||||||
/** 视图层逻辑代码分离演示 */
|
/** 视图层逻辑代码分离演示 */
|
||||||
@property(Node)
|
@property(Node)
|
||||||
card1:Node = null
|
card1:Node = null!
|
||||||
@property(Node)
|
@property(Node)
|
||||||
card2:Node = null
|
card2:Node = null!
|
||||||
@property(Node)
|
@property(Node)
|
||||||
card3:Node = null
|
card3:Node = null!
|
||||||
@property(Node)
|
@property(Node)
|
||||||
card4:Node = null
|
card4:Node = null!
|
||||||
|
|
||||||
|
card1_data:ItalConf = null!
|
||||||
|
card2_data:ItalConf = null!
|
||||||
|
card3_data:ItalConf = null!
|
||||||
|
card4_data:ItalConf = null!
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
oops.message.on(GameEvent.TalentSelect, this.onTalentSelect, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDestroy() {
|
||||||
|
oops.message.off(GameEvent.TalentSelect, this.onTalentSelect, this);
|
||||||
|
this.ent.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
card1_data:any = {}
|
|
||||||
card2_data:any = {}
|
|
||||||
card3_data:any = {}
|
|
||||||
card4_data:any = {}
|
|
||||||
start() {
|
start() {
|
||||||
this.card1.active=true
|
// 初始隐藏或显示逻辑
|
||||||
this.card2.active=true
|
this.node.active = false;
|
||||||
this.card3.active=true
|
this.resetCardStates();
|
||||||
this.card4.active=true
|
|
||||||
}
|
}
|
||||||
refCards(){
|
|
||||||
|
|
||||||
|
private resetCardStates() {
|
||||||
|
const cards = [this.card1, this.card2, this.card3, this.card4];
|
||||||
|
cards.forEach(card => {
|
||||||
|
if (card) {
|
||||||
|
const selected = card.getChildByName("selected");
|
||||||
|
if (selected) selected.active = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
updateCardInfo(card:Node,data:any){
|
|
||||||
|
// 是否已经选择了天赋
|
||||||
|
private hasSelected: boolean = false;
|
||||||
|
|
||||||
|
private onTalentSelect(event: string, args: any) {
|
||||||
|
this.node.active = true;
|
||||||
|
this.hasSelected = false; // 重置选择状态
|
||||||
|
this.resetCardStates(); // 每次刷新前重置卡片状态
|
||||||
|
this.refCards();
|
||||||
|
}
|
||||||
|
|
||||||
|
refCards(){
|
||||||
|
// 随机获取4个不一样的天赋
|
||||||
|
const allTalents = Object.values(talConf);
|
||||||
|
const result: ItalConf[] = [];
|
||||||
|
const temp = [...allTalents];
|
||||||
|
|
||||||
|
// 简单的随机抽取算法
|
||||||
|
for (let i = 0; i < 4 && temp.length > 0; i++) {
|
||||||
|
const index = Math.floor(Math.random() * temp.length);
|
||||||
|
result.push(temp[index]);
|
||||||
|
temp.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新卡片
|
||||||
|
if (result.length > 0) this.updateCardData(1, result[0]);
|
||||||
|
if (result.length > 1) this.updateCardData(2, result[1]);
|
||||||
|
if (result.length > 2) this.updateCardData(3, result[2]);
|
||||||
|
if (result.length > 3) this.updateCardData(4, result[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCardInfo(card:Node, data:ItalConf){
|
||||||
if(!card) return
|
if(!card) return
|
||||||
|
card.active = true;
|
||||||
|
// 隐藏选中状态
|
||||||
|
const selected = card.getChildByName("selected");
|
||||||
|
if(selected) selected.active = false;
|
||||||
|
|
||||||
let name = card.getChildByName("name")
|
let name = card.getChildByName("name")
|
||||||
if(name){
|
if(name){
|
||||||
name.getComponent(Label).string = data.name
|
name.getComponent(Label)!.string = data.name
|
||||||
}
|
}
|
||||||
let info = card.getChildByName("info").getChildByName("Label")
|
let info = card.getChildByName("info")?.getChildByName("Label")
|
||||||
if(info){
|
if(info){
|
||||||
info.getComponent(Label).string = data.info
|
info.getComponent(Label)!.string = data.desc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateCardData(index:number,data:any){
|
|
||||||
|
updateCardData(index:number, data:ItalConf){
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 1:
|
case 1:
|
||||||
this.card1_data = data
|
this.card1_data = data
|
||||||
|
this.updateCardInfo(this.card1, data);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
this.card2_data = data
|
this.card2_data = data
|
||||||
|
this.updateCardInfo(this.card2, data);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
this.card3_data = data
|
this.card3_data = data
|
||||||
|
this.updateCardInfo(this.card3, data);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
this.card4_data = data
|
this.card4_data = data
|
||||||
|
this.updateCardInfo(this.card4, data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
selectCard(index:number){
|
|
||||||
|
|
||||||
|
selectCard(e:any,index:string){
|
||||||
|
console.log("selectCard",index)
|
||||||
|
let _index = parseInt(index);
|
||||||
|
// 如果已经选择过,则不再处理
|
||||||
|
if(this.hasSelected) return;
|
||||||
|
|
||||||
|
let selectedTalent: ItalConf | null = null;
|
||||||
|
let selectedCardNode: Node | null = null;
|
||||||
|
|
||||||
|
switch (_index) {
|
||||||
|
case 1:
|
||||||
|
selectedTalent = this.card1_data;
|
||||||
|
selectedCardNode = this.card1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
selectedTalent = this.card2_data;
|
||||||
|
selectedCardNode = this.card2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
selectedTalent = this.card3_data;
|
||||||
|
selectedCardNode = this.card3;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
selectedTalent = this.card4_data;
|
||||||
|
selectedCardNode = this.card4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedTalent && selectedCardNode) {
|
||||||
|
this.hasSelected = true;
|
||||||
|
console.log("选择天赋:", selectedTalent.name);
|
||||||
|
|
||||||
|
// 显示当前选中的 selected 节点
|
||||||
|
const selected = selectedCardNode.getChildByName("selected");
|
||||||
|
if(selected) selected.active = true;
|
||||||
|
|
||||||
|
// 发送事件
|
||||||
|
oops.message.dispatchEvent(GameEvent.UseTalentCard, selectedTalent.uuid);
|
||||||
|
|
||||||
|
// 延迟关闭界面,让玩家看到选中效果
|
||||||
|
// this.scheduleOnce(() => {
|
||||||
|
// this.node.active = false;
|
||||||
|
// }, 0.5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/** 全局消息逻辑处理 */
|
|
||||||
// private onHandler(event: string, args: any) {
|
|
||||||
// switch (event) {
|
|
||||||
// case ModuleEvent.Cmd:
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
|
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
|
||||||
reset() {
|
reset() {
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ export class MissionComp extends CCComp {
|
|||||||
to_fight(){
|
to_fight(){
|
||||||
smc.mission.in_fight=true
|
smc.mission.in_fight=true
|
||||||
oops.message.dispatchEvent(GameEvent.FightStart) //GameSetMonComp 监听刷怪
|
oops.message.dispatchEvent(GameEvent.FightStart) //GameSetMonComp 监听刷怪
|
||||||
|
oops.message.dispatchEvent(GameEvent.TalentSelect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user