Adding initial support for conquering nodes.
This commit is contained in:
parent
16888b9fdb
commit
389f325618
@ -24,6 +24,7 @@ import NewNodeUI from '@burguillosinfo/conquer/interface/new-node'
|
|||||||
import NewTeamUI from '@burguillosinfo/conquer/interface/new-team'
|
import NewTeamUI from '@burguillosinfo/conquer/interface/new-team'
|
||||||
import WebSocket from '@burguillosinfo/conquer/websocket'
|
import WebSocket from '@burguillosinfo/conquer/websocket'
|
||||||
import JsonSerializer from '@burguillosinfo/conquer/serializer';
|
import JsonSerializer from '@burguillosinfo/conquer/serializer';
|
||||||
|
import ConquerUser from '@burguillosinfo/conquer/user'
|
||||||
|
|
||||||
type StylesInterface = Record<string, Style>
|
type StylesInterface = Record<string, Style>
|
||||||
|
|
||||||
@ -433,13 +434,21 @@ export default class Conquer {
|
|||||||
if (this.currentPositionFeature === null) {
|
if (this.currentPositionFeature === null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const user = await ConquerUser.getSelfUser()
|
||||||
|
let color = 'white';
|
||||||
|
if (user !== null) {
|
||||||
|
const team = await user.getTeam();
|
||||||
|
if (team !== null) {
|
||||||
|
color = team.getColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
const styles: StylesInterface = {
|
const styles: StylesInterface = {
|
||||||
currentPositionFeature: new Style({
|
currentPositionFeature: new Style({
|
||||||
image: new CircleStyle({
|
image: new CircleStyle({
|
||||||
radius: 14,
|
radius: 14,
|
||||||
fill: new Fill({color: 'white'}),
|
fill: new Fill({color: color}),
|
||||||
stroke: new Stroke({
|
stroke: new Stroke({
|
||||||
color: 'blue',
|
color: 'beige',
|
||||||
width: 2,
|
width: 2,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -447,7 +456,7 @@ export default class Conquer {
|
|||||||
};
|
};
|
||||||
const features = [this.currentPositionFeature]
|
const features = [this.currentPositionFeature]
|
||||||
for (const key in this.getServerNodes()) {
|
for (const key in this.getServerNodes()) {
|
||||||
styles[key] = this.getServerNodes()[key].getStyle()
|
styles[key] = await this.getServerNodes()[key].getStyle()
|
||||||
features.push(this.getServerNodes()[key].getFeature())
|
features.push(this.getServerNodes()[key].getFeature())
|
||||||
}
|
}
|
||||||
const vectorLayer = new VectorLayer<VectorSource>({
|
const vectorLayer = new VectorLayer<VectorSource>({
|
||||||
|
@ -63,6 +63,7 @@ export default class NodeView extends AbstractTopBarInterface {
|
|||||||
+ (this.node.isNear()
|
+ (this.node.isNear()
|
||||||
? 'Estas cerca y puedes interactuar con este sitio.'
|
? 'Estas cerca y puedes interactuar con este sitio.'
|
||||||
: 'Estás demasiado lejos para hacer nada aquí.');
|
: 'Estás demasiado lejos para hacer nada aquí.');
|
||||||
|
this.populateTeamData();
|
||||||
if (this.node.isNear()) {
|
if (this.node.isNear()) {
|
||||||
await this.runIfNear();
|
await this.runIfNear();
|
||||||
}
|
}
|
||||||
@ -70,22 +71,87 @@ export default class NodeView extends AbstractTopBarInterface {
|
|||||||
mainNode.classList.remove('conquer-display-none')
|
mainNode.classList.remove('conquer-display-none')
|
||||||
}
|
}
|
||||||
|
|
||||||
private async runIfNear(): Promise<void> {
|
private async populateTeamData() {
|
||||||
const team = await this.user.getTeam();
|
const element = document.createElement('p');
|
||||||
|
const team = await this.node.getTeam();
|
||||||
|
(() => {
|
||||||
if (team === null) {
|
if (team === null) {
|
||||||
|
element.innerText = 'El nodo no pertenece a ningún equipo todavía.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const spanText = document.createElement('span');
|
||||||
|
spanText.innerText = 'Equipo: ';
|
||||||
|
element.append(spanText);
|
||||||
|
const spanCircle = document.createElement('span');
|
||||||
|
spanCircle.classList.add('conquer-team-circle');
|
||||||
|
spanCircle.style.backgroundColor = team.getColor();
|
||||||
|
element.append(spanCircle);
|
||||||
|
const spanTeamName = document.createElement('span');
|
||||||
|
spanTeamName.style.color = team.getColor();
|
||||||
|
spanTeamName.innerText = ' ' + team.getName();
|
||||||
|
element.append(spanTeamName);
|
||||||
|
})();
|
||||||
|
this.getView().append(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async runIfNear(): Promise<void> {
|
||||||
|
const userTeam = await this.user.getTeam();
|
||||||
|
const nodeTeam = await this.node.getTeam();
|
||||||
|
if (userTeam === null) {
|
||||||
const paragraphNoTeam = document.createElement('p');
|
const paragraphNoTeam = document.createElement('p');
|
||||||
paragraphNoTeam.innerText = 'Parece que no has seleccionado equipo aun,'
|
paragraphNoTeam.innerText = 'Parece que no has seleccionado equipo aun,'
|
||||||
+ ' pulsa el botón de seleccionar equipo para comenzar tu aventura,'
|
+ ' pulsa el botón de seleccionar equipo para comenzar tu aventura,'
|
||||||
+ ' si quieres cambiar de equipo en el futuro puedes hacerlo sin problemas.';
|
+ ' si quieres cambiar de equipo en el futuro puedes hacerlo sin problemas.';
|
||||||
this.getView().append(paragraphNoTeam);
|
this.getView().append(paragraphNoTeam);
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectTeamButton = document.createElement('button');
|
const selectTeamButton = document.createElement('button');
|
||||||
selectTeamButton.innerText = 'Seleccionar equipo';
|
selectTeamButton.innerText = 'Seleccionar equipo';
|
||||||
selectTeamButton.addEventListener('click', () => {
|
selectTeamButton.addEventListener('click', () => {
|
||||||
this.runCallbacks('open-select-team');
|
this.runCallbacks('open-select-team');
|
||||||
this.runCallbacks('close');
|
this.runCallbacks('close');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.getView().append(selectTeamButton);
|
this.getView().append(selectTeamButton);
|
||||||
|
if (await this.isOpposingNode()) {
|
||||||
|
const conquerForTeamButton = document.createElement('button');
|
||||||
|
conquerForTeamButton.innerText = 'Conquistar';
|
||||||
|
conquerForTeamButton.addEventListener('click', () => {
|
||||||
|
this.conquerThisNodeForTeam();
|
||||||
|
});
|
||||||
|
this.getView().append(conquerForTeamButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async conquerThisNodeForTeam() {
|
||||||
|
const urlNode = new URL('/conquer/node/' + this.node.getUUID() + '/try-conquer',
|
||||||
|
window.location.protocol + '//'
|
||||||
|
+ window.location.hostname + ':'
|
||||||
|
+ window.location.port)
|
||||||
|
const response = await fetch(urlNode, {
|
||||||
|
method: 'POST',
|
||||||
|
});
|
||||||
|
this.runCallbacks('update-nodes');
|
||||||
|
this.runCallbacks('close');
|
||||||
|
}
|
||||||
|
|
||||||
|
private async isOpposingNode(): Promise<boolean> {
|
||||||
|
const userTeam = await this.user.getTeam();
|
||||||
|
const nodeTeam = await this.node.getTeam();
|
||||||
|
if (userTeam === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (nodeTeam === null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (nodeTeam.getUUID() !== userTeam.getUUID()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async isNodeFree(): Promise<boolean> {
|
||||||
|
return await this.node.getTeam() === null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import InterfaceManager from '@burguillosinfo/conquer/interface-manager'
|
|||||||
import NodeView from '@burguillosinfo/conquer/interface/node-view'
|
import NodeView from '@burguillosinfo/conquer/interface/node-view'
|
||||||
import JsonSerializer from '@burguillosinfo/conquer/serializer';
|
import JsonSerializer from '@burguillosinfo/conquer/serializer';
|
||||||
import SelectTeamUI from '@burguillosinfo/conquer/interface/select-team';
|
import SelectTeamUI from '@burguillosinfo/conquer/interface/select-team';
|
||||||
|
import ConquerTeam from '@burguillosinfo/conquer/team';
|
||||||
|
|
||||||
@JsonObject()
|
@JsonObject()
|
||||||
export default class MapNode {
|
export default class MapNode {
|
||||||
@ -24,9 +25,18 @@ export default class MapNode {
|
|||||||
@JsonProperty() private description: string,
|
@JsonProperty() private description: string,
|
||||||
@JsonProperty() private kind: string,
|
@JsonProperty() private kind: string,
|
||||||
@JsonProperty() private is_near: boolean,
|
@JsonProperty() private is_near: boolean,
|
||||||
|
@JsonProperty() private team: string,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getTeam(): Promise<ConquerTeam | null> {
|
||||||
|
if (this.team === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ConquerTeam.getTeam(this.team);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public async fetch(): Promise<MapNode> {
|
public async fetch(): Promise<MapNode> {
|
||||||
const urlNode = new URL('/conquer/node/' + this.uuid, window.location.protocol + '//' + window.location.hostname + ':' + window.location.port)
|
const urlNode = new URL('/conquer/node/' + this.uuid, window.location.protocol + '//' + window.location.hostname + ':' + window.location.port)
|
||||||
const response = await fetch(urlNode);
|
const response = await fetch(urlNode);
|
||||||
@ -125,11 +135,16 @@ export default class MapNode {
|
|||||||
return this.feature;
|
return this.feature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getStyle(): Style {
|
public async getStyle(): Promise<Style> {
|
||||||
|
const team = await this.getTeam();
|
||||||
|
let color = 'white';
|
||||||
|
if (team !== null) {
|
||||||
|
color = team.getColor();
|
||||||
|
}
|
||||||
return new Style({
|
return new Style({
|
||||||
image: new CircleStyle({
|
image: new CircleStyle({
|
||||||
radius: 14,
|
radius: 14,
|
||||||
fill: new Fill({color: 'white'}),
|
fill: new Fill({color: color}),
|
||||||
stroke: new Stroke({
|
stroke: new Stroke({
|
||||||
color: 'gray',
|
color: 'gray',
|
||||||
width: 2,
|
width: 2,
|
||||||
|
@ -101,6 +101,7 @@ sub startup ($self) {
|
|||||||
$r->put('/conquer/node')->to('ConquerNode#create');
|
$r->put('/conquer/node')->to('ConquerNode#create');
|
||||||
$r->get('/conquer/node/near')->to('ConquerNode#nearbyNodes');
|
$r->get('/conquer/node/near')->to('ConquerNode#nearbyNodes');
|
||||||
$r->get('/conquer/node/<uuid>')->to('ConquerNode#get');
|
$r->get('/conquer/node/<uuid>')->to('ConquerNode#get');
|
||||||
|
$r->post('/conquer/node/<uuid>/try-conquer')->to('ConquerNode#tryConquer');
|
||||||
$r->get('/conquer/user')->to('UserConquer#get_self');
|
$r->get('/conquer/user')->to('UserConquer#get_self');
|
||||||
$r->post('/conquer/user/login')->to('UserConquer#login');
|
$r->post('/conquer/user/login')->to('UserConquer#login');
|
||||||
$r->get('/conquer/tile/<zoom>/<x>/<y>.png')->to('ConquerTile#tile');
|
$r->get('/conquer/tile/<zoom>/<x>/<y>.png')->to('ConquerTile#tile');
|
||||||
|
@ -33,6 +33,33 @@ sub get($self) {
|
|||||||
return $self->render(json => $node->serialize());
|
return $self->render(json => $node->serialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub tryConquer($self) {
|
||||||
|
my $user = $self->current_user;
|
||||||
|
my $schema = BurguillosInfo::Schema->Schema->resultset('ConquerNode');
|
||||||
|
if (!defined $user) {
|
||||||
|
return $self->render(status => 401, json => {
|
||||||
|
error => 'You must be logged to conquer a node.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!defined $user->team) {
|
||||||
|
return $self->render(status => 400, json => {
|
||||||
|
error => 'You must belong to a team to conquer a node.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
my $uuid = $self->param('uuid');
|
||||||
|
my ($node) = $schema->search({uuid => $uuid});
|
||||||
|
if (!defined $node) {
|
||||||
|
return $self->render(status => 404, json => {
|
||||||
|
error => 'No existe ese nodo.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$node->team($user->team);
|
||||||
|
$node->update;
|
||||||
|
$self->render(json => {
|
||||||
|
ok => $JSON::true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
sub create ($self) {
|
sub create ($self) {
|
||||||
my $user = $self->current_user;
|
my $user = $self->current_user;
|
||||||
if ( !defined $user ) {
|
if ( !defined $user ) {
|
||||||
|
@ -37,29 +37,39 @@ __PACKAGE__->add_columns(
|
|||||||
data_type => 'geometry',
|
data_type => 'geometry',
|
||||||
is_nullable => 0,
|
is_nullable => 0,
|
||||||
},
|
},
|
||||||
|
team => {
|
||||||
|
data_type => 'uuid',
|
||||||
|
is_nullable => 1,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
sub coordinate_2($self) {
|
sub coordinate_2 ($self) {
|
||||||
require BurguillosInfo::Schema;
|
require BurguillosInfo::Schema;
|
||||||
my $resultset = BurguillosInfo::Schema->Schema->resultset('ConquerNode');
|
my $resultset = BurguillosInfo::Schema->Schema->resultset('ConquerNode');
|
||||||
my ($new_self) = $resultset->search({uuid => $self->uuid}, {
|
my ($new_self) = $resultset->search(
|
||||||
|
{ uuid => $self->uuid },
|
||||||
|
{
|
||||||
'+select' => {
|
'+select' => {
|
||||||
ST_Y => { ST_Centroid => 'geometry' },
|
ST_Y => { ST_Centroid => 'geometry' },
|
||||||
-as => 'coordinate_2',
|
-as => 'coordinate_2',
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
return $new_self->get_column('coordinate_2');
|
return $new_self->get_column('coordinate_2');
|
||||||
}
|
}
|
||||||
|
|
||||||
sub coordinate_1($self) {
|
sub coordinate_1 ($self) {
|
||||||
require BurguillosInfo::Schema;
|
require BurguillosInfo::Schema;
|
||||||
my $resultset = BurguillosInfo::Schema->Schema->resultset('ConquerNode');
|
my $resultset = BurguillosInfo::Schema->Schema->resultset('ConquerNode');
|
||||||
my ($new_self) = $resultset->search({uuid => $self->uuid}, {
|
my ($new_self) = $resultset->search(
|
||||||
|
{ uuid => $self->uuid },
|
||||||
|
{
|
||||||
'+select' => {
|
'+select' => {
|
||||||
ST_X => { ST_Centroid => 'geometry' },
|
ST_X => { ST_Centroid => 'geometry' },
|
||||||
-as => 'coordinate_1',
|
-as => 'coordinate_1',
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
return $new_self->get_column('coordinate_1');
|
return $new_self->get_column('coordinate_1');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +84,7 @@ sub serialize ( $self, $player = undef ) {
|
|||||||
coordinate_1 => $self->coordinate_1,
|
coordinate_1 => $self->coordinate_1,
|
||||||
coordinate_2 => $self->coordinate_2,
|
coordinate_2 => $self->coordinate_2,
|
||||||
is_near => $self->is_near($player),
|
is_near => $self->is_near($player),
|
||||||
|
team => $self->team,
|
||||||
};
|
};
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
@ -82,22 +93,29 @@ sub is_near ( $self, $player ) {
|
|||||||
if ( !defined $player ) {
|
if ( !defined $player ) {
|
||||||
return $JSON::false;
|
return $JSON::false;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Meters
|
# Meters
|
||||||
if ($self->get_distance_to_player($player) < 100) {
|
if ( $self->get_distance_to_player($player) < 100 ) {
|
||||||
return $JSON::true;
|
return $JSON::true;
|
||||||
}
|
}
|
||||||
return $JSON::false;
|
return $JSON::false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_distance_to_player ($self, $player) {
|
sub get_distance_to_player ( $self, $player ) {
|
||||||
my $longitude_player = $player->last_coordinate_1;
|
my $longitude_player = $player->last_coordinate_1;
|
||||||
my $latitude_player = $player->last_coordinate_2;
|
my $latitude_player = $player->last_coordinate_2;
|
||||||
my $longitude_node = $self->coordinate_1;
|
my $longitude_node = $self->coordinate_1;
|
||||||
my $latitude_node = $self->coordinate_2;
|
my $latitude_node = $self->coordinate_2;
|
||||||
my $gis = GIS::Distance->new;
|
my $gis = GIS::Distance->new;
|
||||||
|
|
||||||
# Setting distance to meters.
|
# Setting distance to meters.
|
||||||
my $distance = $gis->distance_metal( $latitude_node, $longitude_node, $latitude_player, $longitude_player) * 1000;
|
my $distance = $gis->distance_metal(
|
||||||
|
$latitude_node, $longitude_node,
|
||||||
|
$latitude_player, $longitude_player
|
||||||
|
) * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
__PACKAGE__->set_primary_key('uuid');
|
__PACKAGE__->set_primary_key('uuid');
|
||||||
|
__PACKAGE__->belongs_to( 'team_object',
|
||||||
|
'BurguillosInfo::Schema::Result::ConquerTeam', 'team' );
|
||||||
1;
|
1;
|
||||||
|
@ -39,6 +39,7 @@ __PACKAGE__->add_columns(
|
|||||||
|
|
||||||
__PACKAGE__->set_primary_key('uuid');
|
__PACKAGE__->set_primary_key('uuid');
|
||||||
__PACKAGE__->has_many( players => 'BurguillosInfo::Schema::Result::ConquerUser', 'team');
|
__PACKAGE__->has_many( players => 'BurguillosInfo::Schema::Result::ConquerUser', 'team');
|
||||||
|
__PACKAGE__->has_many( nodes => 'BurguillosInfo::Schema::Result::ConquerNode', 'team');
|
||||||
|
|
||||||
sub serialize ($self) {
|
sub serialize ($self) {
|
||||||
$self = $self->get_from_storage();
|
$self = $self->get_from_storage();
|
||||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user