WIP
This commit is contained in:
parent
542f24c12d
commit
3c3c880a3c
@ -1,5 +1,5 @@
|
||||
<!-- Hero Selection Screen -->
|
||||
<nb-card *ngIf="!hero" class="hero-selection-card">
|
||||
<!-- Hero Selection Screen - Initial -->
|
||||
<nb-card *ngIf="!hero && !isSelectingHero" class="hero-selection-card">
|
||||
<nb-card-body class="hero-selection-body">
|
||||
<div class="hero-selection-content">
|
||||
<h2 class="hero-selection-title">Choose Your Hero</h2>
|
||||
@ -11,6 +11,77 @@
|
||||
</div>
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
|
||||
<!-- Hero Selection Panel -->
|
||||
<div *ngIf="!hero && isSelectingHero && currentSelectingHero" class="hero-selection-panel">
|
||||
<div class="row no-gutters hero-selection-row">
|
||||
<div class="col-12 hero-selection-left">
|
||||
<div class="hero-selection-card-wrapper">
|
||||
<div class="hero-selection-header">
|
||||
<div class="hero-selection-title-bar">
|
||||
<h3 class="hero-selection-hero-name">{{currentSelectingHero.name}}</h3>
|
||||
<span class="hero-selection-class">{{HeroClass[selectedHeroClass]}}</span>
|
||||
<span class="hero-selection-counter">({{currentHeroIndex + 1}} / {{heros.length}})</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-selection-content-area">
|
||||
<div class="row no-gutters h-100">
|
||||
<div class="col-6 hero-select-image-col">
|
||||
<div class="hero-select-image-wrapper">
|
||||
<img src="{{imgUrl('Heros/'+className+'.jpg')}}" class="hero-select-image"
|
||||
alt="{{currentSelectingHero.name}}">
|
||||
<!-- HP and Mana Bars -->
|
||||
<div class="hero-select-stats-overlay">
|
||||
<div class="stat-bar-overlay hp-bar-overlay">
|
||||
<div class="stat-bar-label-overlay">
|
||||
<md2-icon [icon]="MD2Icon.HP_Color" size="sm"></md2-icon>
|
||||
<span class="stat-value-overlay">{{currentSelectingHero.hpMaximum}}</span>
|
||||
</div>
|
||||
<div class="stat-progress-bar-overlay">
|
||||
<div class="stat-progress-fill-overlay hp-fill-overlay full-stat"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-bar-overlay mp-bar-overlay">
|
||||
<div class="stat-bar-label-overlay">
|
||||
<md2-icon [icon]="MD2Icon.Mana_Color" size="sm"></md2-icon>
|
||||
<span class="stat-value-overlay">{{currentSelectingHero.mpMaximum}}</span>
|
||||
</div>
|
||||
<div class="stat-progress-bar-overlay">
|
||||
<div class="stat-progress-fill-overlay mp-fill-overlay full-stat"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 hero-select-skills-col">
|
||||
<div class="hero-select-skills">
|
||||
<div class="skills-title">Abilities</div>
|
||||
<div class="skill-content" [innerHTML]="currentSelectingHero.skillHtml"></div>
|
||||
<div class="skills-title shadow-skills-title">Shadow Abilities</div>
|
||||
<div class="skill-content shadow-skill-content"
|
||||
[innerHTML]="currentSelectingHero.shadowSkillHtml"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-selection-actions">
|
||||
<button nbButton hero status="basic" class="nav-hero-btn" (click)="previousHero()">
|
||||
<nb-icon icon="chevron-back-outline" class="mr-1"></nb-icon>
|
||||
Previous
|
||||
</button>
|
||||
<button nbButton hero status="primary" class="select-hero-btn" (click)="selectCurrentHero()">
|
||||
<nb-icon icon="checkmark-circle-outline" class="mr-2"></nb-icon>
|
||||
It's Me!
|
||||
</button>
|
||||
<button nbButton hero status="basic" class="nav-hero-btn" (click)="nextHero()">
|
||||
Next
|
||||
<nb-icon icon="chevron-forward-outline" class="ml-1"></nb-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="hero">
|
||||
<div class="row no-gutters">
|
||||
<div class="col-12 col-sm-7">
|
||||
@ -202,7 +273,7 @@
|
||||
|
||||
</div>
|
||||
<div *ngIf="md2Service.info.isBossFight"></div>
|
||||
<div class="d-sm-none">
|
||||
<!-- <div class="d-sm-none">
|
||||
<div *ngIf="hero.uiActivating&&hero.remainActions>0">
|
||||
<button nbButton hero class="mr-2" status="info" (click)="moveAction()"
|
||||
*ngIf="!showMoveAction">Move</button>
|
||||
@ -219,7 +290,7 @@
|
||||
|
||||
<button nbButton hero fullWidth status="info" *ngIf="allowStartAction"
|
||||
(click)="startActivation()">Start Activation</button>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
|
||||
<button nbButton hero status="info" class="mt-2" (click)="openDoor()" *ngIf="showMoveAction">Open
|
||||
|
||||
@ -65,6 +65,300 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Hero Selection Panel
|
||||
.hero-selection-panel {
|
||||
height: 85vh;
|
||||
max-height: 85vh;
|
||||
padding: 0.5rem;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@media (orientation: landscape) {
|
||||
height: 85vh;
|
||||
max-height: 85vh;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) {
|
||||
height: 85vh;
|
||||
max-height: 85vh;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) and (max-height: 667px) {
|
||||
height: 85vh;
|
||||
max-height: 85vh;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
height: 85vh;
|
||||
max-height: 85vh;
|
||||
padding: 0.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-selection-row {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.hero-selection-left {
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-selection-card-wrapper {
|
||||
height: 100%;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-selection-header {
|
||||
padding: 0.75rem 1rem;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border-bottom: 2px solid rgba(255, 255, 255, 0.2);
|
||||
flex-shrink: 0;
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-selection-title-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) and (max-width: 767px) {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-selection-hero-name {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) and (max-width: 767px) {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-selection-class {
|
||||
font-size: 0.85rem;
|
||||
opacity: 0.9;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
font-weight: 500;
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) and (max-width: 767px) {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-selection-counter {
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.8;
|
||||
margin-left: auto;
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
font-size: 0.65rem;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) and (max-width: 767px) {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-selection-content-area {
|
||||
flex: 1;
|
||||
padding: 0.75rem;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
padding: 0.4rem;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) and (max-width: 767px) {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-select-image-col,
|
||||
.hero-select-skills-col {
|
||||
padding: 0.4rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
padding: 0.2rem;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) and (max-width: 767px) {
|
||||
padding: 0.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-select-image-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
background: #f8f9fa;
|
||||
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hero-select-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.hero-select-stats-overlay {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 0.5rem;
|
||||
background: linear-gradient(to top, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.5) 70%, transparent 100%);
|
||||
border-radius: 0 0 8px 8px;
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
padding: 0.35rem;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-select-skills {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 0.75rem;
|
||||
overflow-y: auto;
|
||||
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
min-height: 0;
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
padding: 0.4rem;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) and (max-width: 767px) {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-selection-actions {
|
||||
padding: 0.75rem;
|
||||
border-top: 2px solid #e9ecef;
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
padding: 0.5rem;
|
||||
gap: 0.35rem;
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) and (max-width: 767px) {
|
||||
padding: 0.5rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-hero-btn {
|
||||
flex: 1;
|
||||
min-height: 40px;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
transition: all 0.3s;
|
||||
padding: 0.5rem;
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
min-height: 32px;
|
||||
font-size: 0.75rem;
|
||||
padding: 0.35rem 0.5rem;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) and (max-width: 767px) {
|
||||
min-height: 38px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
.select-hero-btn {
|
||||
flex: 2;
|
||||
min-height: 40px;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
|
||||
transition: all 0.3s;
|
||||
padding: 0.5rem;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 16px rgba(102, 126, 234, 0.5);
|
||||
}
|
||||
|
||||
@media (max-height: 450px) and (orientation: landscape) {
|
||||
min-height: 32px;
|
||||
font-size: 0.8rem;
|
||||
padding: 0.35rem 0.5rem;
|
||||
}
|
||||
|
||||
@media (orientation: portrait) and (max-width: 767px) {
|
||||
min-height: 38px;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
||||
|
||||
.MD2Hp {
|
||||
font-size: xx-large;
|
||||
position: fixed;
|
||||
@ -291,6 +585,10 @@
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
|
||||
animation: shimmer 2s infinite;
|
||||
}
|
||||
|
||||
&.full-stat {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.hp-fill-overlay {
|
||||
|
||||
@ -58,11 +58,18 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
||||
];
|
||||
heros = [] as MD2HeroInfo[];
|
||||
heroProfiles: MD2HeroProfile[] = [];
|
||||
currentHeroIndex: number = 0;
|
||||
isSelectingHero: boolean = false;
|
||||
selectedHeroClass: HeroClass;
|
||||
|
||||
public get hero() {
|
||||
return this.md2Service.playerHero;
|
||||
}
|
||||
|
||||
public get currentSelectingHero(): MD2HeroInfo {
|
||||
return this.heros[this.currentHeroIndex];
|
||||
}
|
||||
|
||||
constructor(
|
||||
private gameRoomService: GameRoomService,
|
||||
public md2Service: MD2Service,
|
||||
@ -119,46 +126,56 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
||||
initClassHeroList(heroClass: HeroClass) {
|
||||
this.heros = [];
|
||||
this.className = HeroClass[heroClass];
|
||||
this.selectedHeroClass = heroClass;
|
||||
this.heroProfileService.getAll().pipe(first()).subscribe(result => {
|
||||
|
||||
this.heroProfiles = result;
|
||||
this.heroProfiles = result.filter(h => h.heroClass == heroClass);
|
||||
for (let i = 0; i < this.heroProfiles.length; i++) {
|
||||
const heroProfile = this.heroProfiles[i];
|
||||
this.heros.push(new MD2HeroInfo({
|
||||
const heroInfo = new MD2HeroInfo({
|
||||
name: heroProfile.title,
|
||||
mpMaximum: heroProfile.mana,
|
||||
hpMaximum: heroProfile.hp,
|
||||
hp: heroProfile.hp,
|
||||
mp: heroProfile.mana,
|
||||
skillHtml: heroProfile.skillHtml,
|
||||
shadowSkillHtml: heroProfile.shadowSkillHtml,
|
||||
class: heroClass
|
||||
}))
|
||||
});
|
||||
heroInfo.imgUrl = this.imgUrl('Heros/' + HeroClass[heroClass] + '.jpg');
|
||||
this.heros.push(heroInfo);
|
||||
}
|
||||
this.heros = ArrayUtils.Shuffle(this.heros);//.sort((a, b) => StringUtils.compareSemVer(a.name, b.name));
|
||||
this.showHeroList(heroClass, 0);
|
||||
this.currentHeroIndex = 0;
|
||||
this.isSelectingHero = true;
|
||||
this.detectChanges();
|
||||
});
|
||||
|
||||
}
|
||||
showHeroList(heroClass: HeroClass, index: number) {
|
||||
let className = HeroClass[heroClass];
|
||||
let heroInfo = this.heros[index];
|
||||
this.msgBoxService.show(`${className}(${index + 1}/${this.heros.length})`, {
|
||||
text: `<img src='${heroInfo.imgUrl}' class="g-width-50vw-md g-width-80vw">`,
|
||||
buttons: ADButtons.YesNo,
|
||||
cardWidthClass: '',
|
||||
confirmButtonText: 'It\'s Me!',
|
||||
cancelButtonText: 'Next',
|
||||
cancelButtonColor: ADButtonColor.INFO
|
||||
}).pipe(first()).subscribe(result => {
|
||||
if (result) {
|
||||
this.md2Service.playerJoin(heroInfo);
|
||||
|
||||
selectCurrentHero() {
|
||||
if (this.currentSelectingHero) {
|
||||
this.md2Service.playerJoin(this.currentSelectingHero);
|
||||
this.isSelectingHero = false;
|
||||
this.detectChanges();
|
||||
this.gameRoomService.joinGameRoom(this.roomId);
|
||||
} else {
|
||||
index++;
|
||||
if (index == this.heros.length) index = 0;
|
||||
this.showHeroList(heroClass, index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
nextHero() {
|
||||
this.currentHeroIndex++;
|
||||
if (this.currentHeroIndex >= this.heros.length) {
|
||||
this.currentHeroIndex = 0;
|
||||
}
|
||||
this.detectChanges();
|
||||
}
|
||||
|
||||
previousHero() {
|
||||
this.currentHeroIndex--;
|
||||
if (this.currentHeroIndex < 0) {
|
||||
this.currentHeroIndex = this.heros.length - 1;
|
||||
}
|
||||
this.detectChanges();
|
||||
}
|
||||
|
||||
broadcastHeroInfo() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user