feat: support adding locations without them being visible to players
authorxangelo <me@xangelo.ca>
Tue, 27 Aug 2024 12:52:57 +0000 (08:52 -0400)
committerxangelo <me@xangelo.ca>
Tue, 27 Aug 2024 12:52:57 +0000 (08:52 -0400)
This gives us the ability to add items to airtable without them being
visible to the user

migrations/20240320020618_conditional-location.ts [new file with mode: 0644]
seeds/cities.ts
src/server/api.ts
src/server/map.ts
src/server/routes/travel.ts
src/shared/map.ts

diff --git a/migrations/20240320020618_conditional-location.ts b/migrations/20240320020618_conditional-location.ts
new file mode 100644 (file)
index 0000000..0f154ac
--- /dev/null
@@ -0,0 +1,16 @@
+import { Knex } from "knex";
+
+
+export async function up(knex: Knex): Promise<void> {
+  return knex.schema.alterTable('locations', table => {
+    table.boolean('is_visible').defaultTo(true);
+  });
+}
+
+
+export async function down(knex: Knex): Promise<void> {
+  return knex.schema.alterTable('locations', table => {
+    table.dropColumn('is_visible');
+  })
+}
+
index 866907fa490d7c7e27cf970d42f38e548270258b..b4e58d0b9fe3d0925068d3fbbdc1bce96255795e 100644 (file)
@@ -74,7 +74,8 @@ export async function createLocations(): Promise<void> {
           city_id: r.fields.city_id[0],
           display_order: r.fields["Display Order"],
           event_name: r.fields['event_name'],
-          min_level: Math.max(parseInt(r.fields['Min Level'].toString()), 1)
+          min_level: Math.max(parseInt(r.fields['Min Level'].toString()), 1),
+          is_visible: !!(r.fields['Visible'] ?? true)
         }
       })).onConflict('id').merge();
 
index b63d65dd13ed0d08c6034ad59b9c899e1197f3d4..45f7992c568d474a850a198ae9601fdac0248315 100644 (file)
@@ -209,7 +209,7 @@ app.get('/player/explore', authEndpoint, async (req: Request, res: Response) =>
   // display the default explore view
   const [city, locations, paths] = await Promise.all([
     getCityDetails(req.player.city_id),
-    getAllServices(req.player.city_id, req.player.level),
+    getAllServices(req.player.city_id),
     getAllPaths(req.player.city_id)
   ]);
 
index 45b008470c293dcc26d897d8ccf3287f4e71f371..6b99a6c8b641d920be8d0d3d41a30cd41101bcff 100644 (file)
@@ -4,11 +4,11 @@ import type { Travel, TravelWithNames } from '../shared/travel';
 import { db } from './lib/db';
 import { random } from 'lodash';
 
-export async function getAllServices(city_id: number, min_level: number): Promise<Location[]> {
+export async function getAllServices(city_id: number): Promise<Location[]> {
   return db.select('*')
             .from<Location>('locations')
             .where({city_id})
-            .andWhere('min_level', '<=', min_level)
+            .andWhere('is_visible', true)
             .orderBy('type')
             .orderBy('display_order');
 }
index 5e84c24c20e75142cf66f0a536ae82d0e0e9d82b..8ca4597f2e364010e71200467ea7d0e1bf58f439 100644 (file)
@@ -41,7 +41,7 @@ travelRouter.post('/travel/step', authEndpoint, async (req: Request, res: Respon
 
     const [city, locations, paths] = await Promise.all([
       getCityDetails(travel.destination_id),
-      getAllServices(travel.destination_id, req.player.level),
+      getAllServices(travel.destination_id),
       getAllPaths(travel.destination_id)
     ]);
 
@@ -98,7 +98,7 @@ travelRouter.post('/travel/return-to-source', authEndpoint, async (req: Request,
   else {
     const [city, locations, paths] = await Promise.all([
       getCityDetails(req.player.city_id),
-      getAllServices(req.player.city_id, req.player.level),
+      getAllServices(req.player.city_id),
       getAllPaths(req.player.city_id)
     ]);
 
index b4267dbe57d251853639cdd578844cb761c11d4c..acf1f45abbc8eed72331476c77b37f14468e1135 100644 (file)
@@ -14,6 +14,7 @@ export type Location = {
   type: LocationType,
   display_order: number;
   event_name: string;
+  min_level: number;
 }
 
 export type LocationWithCity  = Location & {