Änderung: Hinzufügung der Haus-Logik zur Taxi-Map
Änderungen: - Integration des neuen Modells TaxiMapTileHouse zur Verwaltung von Häusern auf der Karte. - Anpassung der TaxiMap- und TaxiMapService-Logik zur Unterstützung der Hausplatzierung und -verwaltung. - Erweiterung der Benutzeroberfläche in TaxiToolsView.vue zur Erfassung und Anzeige von Hausinformationen. - Implementierung von Methoden zur Speicherung und Aktualisierung von Hausdaten in der Datenbank. Diese Anpassungen verbessern die Funktionalität und Benutzererfahrung im Taxi-Minispiel, indem sie eine detaillierte Verwaltung von Häusern auf der Karte ermöglichen.
This commit is contained in:
@@ -107,6 +107,7 @@ import TaxiLevelStats from './taxi/taxiLevelStats.js';
|
||||
import TaxiMapType from './taxi/taxiMapType.js';
|
||||
import TaxiMap from './taxi/taxiMap.js';
|
||||
import TaxiMapTile from './taxi/taxiMapTile.js';
|
||||
import TaxiMapTileHouse from './taxi/taxiMapTileHouse.js';
|
||||
import TaxiStreetName from './taxi/taxiStreetName.js';
|
||||
import TaxiMapTileStreet from './taxi/taxiMapTileStreet.js';
|
||||
|
||||
@@ -815,4 +816,8 @@ export default function setupAssociations() {
|
||||
|
||||
TaxiMapTileStreet.belongsTo(TaxiStreetName, { foreignKey: 'street_name_h_id', as: 'streetNameH' });
|
||||
TaxiMapTileStreet.belongsTo(TaxiStreetName, { foreignKey: 'street_name_v_id', as: 'streetNameV' });
|
||||
|
||||
// Houses per tile (one row per corner)
|
||||
TaxiMap.hasMany(TaxiMapTileHouse, { foreignKey: 'map_id', as: 'tileHouses' });
|
||||
TaxiMapTileHouse.belongsTo(TaxiMap, { foreignKey: 'map_id', as: 'map' });
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ import Match3UserProgress from './match3/userProgress.js';
|
||||
import Match3UserLevelProgress from './match3/userLevelProgress.js';
|
||||
|
||||
// — Taxi Minigame —
|
||||
import { TaxiGameState, TaxiLevelStats, TaxiMapType, TaxiMap, TaxiMapTile, TaxiStreetName, TaxiMapTileStreet } from './taxi/index.js';
|
||||
import { TaxiGameState, TaxiLevelStats, TaxiMapType, TaxiMap, TaxiMapTile, TaxiStreetName, TaxiMapTileStreet, TaxiMapTileHouse } from './taxi/index.js';
|
||||
|
||||
// — Politische Ämter (Politics) —
|
||||
import PoliticalOfficeType from './falukant/type/political_office_type.js';
|
||||
@@ -242,6 +242,7 @@ const models = {
|
||||
TaxiMapTile,
|
||||
TaxiStreetName,
|
||||
TaxiMapTileStreet,
|
||||
TaxiMapTileHouse,
|
||||
};
|
||||
|
||||
export default models;
|
||||
|
||||
@@ -5,5 +5,6 @@ import TaxiMap from './taxiMap.js';
|
||||
import TaxiMapTile from './taxiMapTile.js';
|
||||
import TaxiStreetName from './taxiStreetName.js';
|
||||
import TaxiMapTileStreet from './taxiMapTileStreet.js';
|
||||
import TaxiMapTileHouse from './taxiMapTileHouse.js';
|
||||
|
||||
export { TaxiGameState, TaxiLevelStats, TaxiMapType, TaxiMap, TaxiMapTile, TaxiStreetName, TaxiMapTileStreet };
|
||||
export { TaxiGameState, TaxiLevelStats, TaxiMapType, TaxiMap, TaxiMapTile, TaxiStreetName, TaxiMapTileStreet, TaxiMapTileHouse };
|
||||
|
||||
56
backend/models/taxi/taxiMapTileHouse.js
Normal file
56
backend/models/taxi/taxiMapTileHouse.js
Normal file
@@ -0,0 +1,56 @@
|
||||
import { DataTypes } from 'sequelize';
|
||||
import { sequelize } from '../../utils/sequelize.js';
|
||||
|
||||
const TaxiMapTileHouse = sequelize.define('TaxiMapTileHouse', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
primaryKey: true,
|
||||
autoIncrement: true
|
||||
},
|
||||
mapId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
x: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
comment: 'X-coordinate of the tile within the map'
|
||||
},
|
||||
y: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
comment: 'Y-coordinate of the tile within the map'
|
||||
},
|
||||
corner: {
|
||||
type: DataTypes.ENUM('lo', 'ro', 'lu', 'ru'),
|
||||
allowNull: false,
|
||||
comment: 'Corner position: lo, ro, lu, ru'
|
||||
},
|
||||
rotation: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 0,
|
||||
comment: 'Rotation in degrees: 0, 90, 180, 270'
|
||||
}
|
||||
}, {
|
||||
tableName: 'taxi_map_tile_house',
|
||||
schema: 'taxi',
|
||||
timestamps: true,
|
||||
underscored: true,
|
||||
indexes: [
|
||||
{
|
||||
unique: true,
|
||||
fields: ['map_id', 'x', 'y', 'corner']
|
||||
},
|
||||
{
|
||||
fields: ['map_id']
|
||||
},
|
||||
{
|
||||
fields: ['x', 'y']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
export default TaxiMapTileHouse;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import TaxiMapType from '../models/taxi/taxiMapType.js';
|
||||
import TaxiMapTile from '../models/taxi/taxiMapTile.js';
|
||||
import TaxiStreetName from '../models/taxi/taxiStreetName.js';
|
||||
import TaxiMapTileStreet from '../models/taxi/taxiMapTileStreet.js';
|
||||
import TaxiMapTileHouse from '../models/taxi/taxiMapTileHouse.js';
|
||||
|
||||
class TaxiMapService extends BaseService {
|
||||
constructor() {
|
||||
@@ -43,7 +44,8 @@ class TaxiMapService extends BaseService {
|
||||
{ model: TaxiStreetName, as: 'streetNameH' },
|
||||
{ model: TaxiStreetName, as: 'streetNameV' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ model: TaxiMapTileHouse, as: 'tileHouses' }
|
||||
],
|
||||
order: [['name', 'ASC']]
|
||||
});
|
||||
@@ -74,7 +76,8 @@ class TaxiMapService extends BaseService {
|
||||
{ model: TaxiStreetName, as: 'streetNameH' },
|
||||
{ model: TaxiStreetName, as: 'streetNameV' }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ model: TaxiMapTileHouse, as: 'tileHouses' }
|
||||
]
|
||||
});
|
||||
return map;
|
||||
@@ -112,7 +115,7 @@ class TaxiMapService extends BaseService {
|
||||
*/
|
||||
async createMap(mapData) {
|
||||
try {
|
||||
const { tiles, tileStreetNames, ...mapFields } = mapData;
|
||||
const { tiles, tileStreetNames, tileHouses, ...mapFields } = mapData;
|
||||
// mapData JSON ist entfernt – map erstellen ohne mapData
|
||||
const map = await TaxiMap.create(mapFields);
|
||||
// Tiles upsert (optional)
|
||||
@@ -123,6 +126,9 @@ class TaxiMapService extends BaseService {
|
||||
if (tileStreetNames && Object.keys(tileStreetNames).length > 0) {
|
||||
await this.upsertTileStreetNames(map.id, tileStreetNames);
|
||||
}
|
||||
if (tileHouses && Object.keys(tileHouses).length > 0) {
|
||||
await this.upsertTileHouses(map.id, tileHouses);
|
||||
}
|
||||
return await this.getMapById(map.id);
|
||||
} catch (error) {
|
||||
console.error('Error creating map:', error);
|
||||
@@ -135,7 +141,7 @@ class TaxiMapService extends BaseService {
|
||||
*/
|
||||
async updateMap(mapId, updateData) {
|
||||
try {
|
||||
const { tiles, tileStreetNames, ...mapFields } = updateData;
|
||||
const { tiles, tileStreetNames, tileHouses, ...mapFields } = updateData;
|
||||
const [updatedRowsCount] = await TaxiMap.update(mapFields, {
|
||||
where: { id: mapId }
|
||||
});
|
||||
@@ -151,6 +157,9 @@ class TaxiMapService extends BaseService {
|
||||
if (tileStreetNames && Object.keys(tileStreetNames).length > 0) {
|
||||
await this.upsertTileStreetNames(mapId, tileStreetNames);
|
||||
}
|
||||
if (tileHouses && Object.keys(tileHouses).length > 0) {
|
||||
await this.upsertTileHouses(mapId, tileHouses);
|
||||
}
|
||||
return await this.getMapById(mapId);
|
||||
} catch (error) {
|
||||
console.error('Error updating map:', error);
|
||||
@@ -205,6 +214,24 @@ class TaxiMapService extends BaseService {
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert Häuser pro Tile (je Ecke eine Zeile)
|
||||
* @param {number} mapId
|
||||
* @param {{[cellKey:string]: {[corner:string]: number}}} tileHouses
|
||||
*/
|
||||
async upsertTileHouses(mapId, tileHouses) {
|
||||
// Löschen und neu anlegen pro Zelle ist am einfachsten und robust
|
||||
const entries = Object.entries(tileHouses || {});
|
||||
for (const [cellKey, cornerMap] of entries) {
|
||||
const [x, y] = cellKey.split(',').map(Number);
|
||||
await TaxiMapTileHouse.destroy({ where: { map_id: mapId, x, y } });
|
||||
for (const [corner, rotation] of Object.entries(cornerMap || {})) {
|
||||
await TaxiMapTileHouse.create({ mapId, x, y, corner, rotation: Number(rotation) || 0 });
|
||||
}
|
||||
}
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Map (soft delete)
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,14 @@ const initializeTaxi = async () => {
|
||||
console.warn('⚠️ Konnte taxi_map_tile nicht synchronisieren:', e?.message || e);
|
||||
}
|
||||
|
||||
// Stelle sicher, dass die neue Tabelle taxi_map_tile_house existiert (Häuser je Ecke)
|
||||
try {
|
||||
await (await import('../models/taxi/taxiMapTileHouse.js')).default.sync({ alter: true, force: false });
|
||||
console.log('✅ Tabelle taxi.taxi_map_tile_house ist synchronisiert');
|
||||
} catch (e) {
|
||||
console.warn('⚠️ Konnte taxi_map_tile_house nicht synchronisieren:', e?.message || e);
|
||||
}
|
||||
|
||||
// Stelle sicher: timestamps-Spalten in taxi_street_name vorhanden (ältere DBs hatten evtl. kein updated_at)
|
||||
try {
|
||||
await sequelize.query(`
|
||||
|
||||
Reference in New Issue
Block a user