5 Commits b32b4c6056 ... 074ba998c7

Auteur SHA1 Message Date
  caryoscelus 074ba998c7 DJII: bleed works il y a 10 mois
  caryoscelus ef8f9bc617 DJII: fix blocks when negative amount il y a 10 mois
  caryoscelus bf58991f11 DJII: test bleed trap WIP il y a 10 mois
  caryoscelus 772e79c4c2 DJII: getSkillLevel il y a 10 mois
  caryoscelus e4ff5a7de0 DJII: Mission.onEntrance il y a 10 mois

+ 33 - 2
src/lib/pos3.ts

@@ -2,7 +2,7 @@
  * 3D position
  */
 
-import { addComponent, defineComponent, hasComponent, Types, type IWorld, defineQuery, type Entity } from './ecs';
+import { addComponent, defineComponent, hasComponent, Types, type IWorld, defineQuery, type Entity, removeComponent, type Component } from './ecs';
 import { isLandscape } from './landscape';
 import { describe } from '$lib';
 
@@ -41,12 +41,19 @@ export const placeOnMap = (world: IWorld, e: Entity, x, y, z) => {
   processLevelTriggers(world, e, undefined, z);
 };
 
+export const removeFromMap = (world, e) => {
+  // const {x, y, z} = getPos3(e);
+  // removeFrom(world, e, x, y);
+  removeComponent(world, Pos3, e);
+  /// TODO
+};
+
 export const moveTo = (world, e, x, y, z) => {
   Pos3.x[e] = x;
   Pos3.y[e] = y;
   Pos3.z[e] = z;
   registerOnGrid(world, e, x, y, z);
-//  processFeatureTriggers(world, e, x, y, z);
+  processLocationTriggers(world, e, x, y, z);
 };
 
 const levelTriggers = [];
@@ -171,3 +178,27 @@ export const getGrid = (world, z, x0, y0, x1, y1) => {
 export const landscapeAt = (world, x: number, y: number, z: number) => {
   return getTile(x, y, z).landscape;
 };
+
+type LocationTrigger = {
+  target: Component,
+  trigger: (world: IWorld, feature: Entity, e: Entity) => void,
+};
+
+const locationTriggers: LocationTrigger[] = [];
+
+export const registerLocationTrigger = (trigger: LocationTrigger) => {
+  locationTriggers.push(trigger);
+};
+
+const processLocationTriggers = (world: IWorld, e: Entity, x: number, y: number, z: number) => {
+  const stack = getStack(x, y, z);
+  for (let other of stack) {
+    if (e === other)
+      continue;
+    for (let {target, trigger} of locationTriggers) {
+      if (hasComponent(world, target, other)) {
+        trigger(world, other, e);
+      }
+    }
+  }
+};

+ 4 - 3
src/routes/djii/attack.ts

@@ -4,7 +4,7 @@ import { Types, defineComponent, type IWorld, type Entity, hasComponent, type Co
 import { log } from '$lib/log';
 import { decode, encode } from '$lib/util';
 import { getEquippedIn } from './equipment';
-import { getSkill } from './skill';
+import { getSkill, getSkillLevel } from './skill';
 
 export const Attackable = defineComponent('Attackable', {});
 
@@ -69,11 +69,12 @@ export const enumAvaliableMeleeStyles = (world: IWorld, e: Entity) => {
 };
 
 export const canUseMeleeStyle = (world: IWorld, e: Entity, style: MeleeStyle) => {
-  return style.skills.every((skill) => hasComponent(world, skill, e));
+  return style.skills.every((skill) => getSkillLevel(world, e, skill) > 0);
 };
 
 const checkStyle = (world: IWorld, style: MeleeStyle, weapon: Entity) => {
-  // TODO
+  if (!style.weaponReq.every((comp) => hasComponent(world, comp, weapon)))
+    return false;
   return true;
 };
 

+ 1 - 0
src/routes/djii/blocks.ts

@@ -3,6 +3,7 @@
  */
 
 export const renderBlocks = ({max, amount}) => {
+  amount = Math.max(0, amount);
   const numBlocks = Math.ceil(max / 4);
   if (amount === max) {
     return '█'.repeat(numBlocks);

+ 10 - 1
src/routes/djii/blood.ts

@@ -1,4 +1,4 @@
-import { Types, defineComponent } from '$lib/ecs';
+import { Types, defineComponent, type IWorld, type Entity } from '$lib/ecs';
 
 export const BloodLevel = defineComponent('Blood', {
   max: Types.i32,
@@ -11,3 +11,12 @@ export const getBloodLevel = (world, e) => {
     amount: BloodLevel.amount[e],
   };
 };
+
+export const loseBlood = (world: IWorld, e: Entity, amount: number) => {
+  const blood = BloodLevel.amount[e] - amount;
+  BloodLevel.amount[e] = blood;
+  if (blood <= 0) {
+    // logPc("loses too much blood!");
+    // creatureDies(world, e);
+  }
+};

+ 50 - 0
src/routes/djii/body.ts

@@ -0,0 +1,50 @@
+import { nullEntity } from '$lib';
+import { registerOnHeartBeat } from '$lib/content/heart';
+import { Types, defineComponent, type Component, type IWorld, type Entity, hasComponent } from '$lib/ecs';
+import { loseBlood } from './blood';
+
+export const BodyPart = {
+  bleeding: Types.i32,
+  bones: Types.i32,
+  bonesMax: Types.i32,
+  muscles: Types.i32,
+  musclesMax: Types.i32,
+  chopped: Types.ui8,
+};
+
+const bodyParts: Component[] = [];
+
+export const registerBodyPart = (comp: Component) => {
+  bodyParts.push(comp);
+  registerOnHeartBeat(comp, (world, e) => {
+    const bleeding = comp.bleeding[e];
+    if (bleeding > 0) {
+      loseBlood(world, e, bleeding);
+    }
+  });
+};
+
+export const enumAllBodyParts = () => {
+  return bodyParts;
+};
+
+export const enumBodyParts = (world: IWorld, e: Entity) => {
+  return enumAllBodyParts().filter((comp) => hasComponent(world, comp, e));
+};
+
+export const defineBodyPart = (name: string) => {
+  const res = defineComponent(name, BodyPart);
+  registerBodyPart(res);
+  return res;
+};
+
+export const applyBleed = (world: IWorld, e: Entity, bodyPart: Component, amount: number) => {
+  bodyPart.bleeding[e] = amount;
+};
+
+export const Head = defineBodyPart('Head');
+export const Torso = defineBodyPart('Torso');
+export const LeftArm = defineBodyPart('LeftArm');
+export const RightArm = defineBodyPart('RightArm');
+export const LeftLeg = defineBodyPart('LeftLeg');
+export const RightLeg = defineBodyPart('RightLeg');

+ 1 - 16
src/routes/djii/human.ts

@@ -6,26 +6,11 @@ import { Eyes } from '$lib/eyes';
 import { Move3Action } from '$lib/walk3';
 import { SelectedMeleeStyle, Stamina, StaminaRegen } from './attack';
 import { BloodLevel } from './blood';
+import { Head, LeftArm, LeftLeg, RightArm, RightLeg, Torso } from './body';
 import { BodySlot, FeetSlot, HandsSlot, HeadSlot, LegsSlot, MainHandSlot, NeckSlot, OffHandSlot } from './equipment';
 
 export const Human = defineComponent('Human', {});
 
-export const BodyPart = {
-  bleeding: Types.i32,
-  bones: Types.i32,
-  bonesMax: Types.i32,
-  muscles: Types.i32,
-  musclesMax: Types.i32,
-  chopped: Types.ui8,
-};
-
-export const Head = defineComponent('Head', BodyPart);
-export const Torso = defineComponent('Torso', BodyPart);
-export const LeftArm = defineComponent('LeftArm', BodyPart);
-export const RightArm = defineComponent('RightArm', BodyPart);
-export const LeftLeg = defineComponent('LeftLeg', BodyPart);
-export const RightLeg = defineComponent('RightLeg', BodyPart);
-
 export const humanTemplate = [
   [Creature],
   [Human],

+ 5 - 1
src/routes/djii/intro.ts

@@ -12,6 +12,7 @@ import { drawRectangle, fillRectangle, floorTemplate, spawnNearby, spawnRandomTh
 import { Mission, registerMissionTemplate } from './mission';
 import { TalkNPC, registerTalkNPC } from './npc';
 import { stairDownTemplate, stairUpTemplate } from './stairs';
+import { bleedTrapTemplate } from './test';
 import { thugTemplate } from './thug';
 import { wallTemplate } from './wall';
 
@@ -60,9 +61,11 @@ registerMissionTemplate('intro', {
         y0 = y;
       }
     }
-    log("After losing livelihood and aimlessly wandering the streets with all but an empty pocket, you've stumbled upon a shady person who offered you a job. Full of doubts and hopes, you've arrived to the appointed building...", 'story-message');
     return [x0, y0, 0];
   },
+  onEntrance: (world, pc) => {
+    log("After losing livelihood and aimlessly wandering the streets with all but an empty pocket, you've stumbled upon a shady person who offered you a job. Full of doubts and hopes, you've arrived to the appointed building...", 'story-message');
+  },
 });
 
 const lobbyFloor = {
@@ -76,6 +79,7 @@ const lobbyFloor = {
     const [x, y] = placeEntrance(world, width, height, z);
     spawnNearby(world, introRecruiterTemplate, x, y, z);
     spawnNearby(world, thugTemplate, x, y, z);
+    spawnNearby(world, bleedTrapTemplate, x, y, z);
     const result = spawnVaultRandom(world, stairwell0VaultTemplate, 1, 1, width-2, height-2, z);
     // const stairwell = stairwells[0];
     // placeMainEntrance()

+ 1 - 1
src/routes/djii/mapgen.ts

@@ -57,7 +57,7 @@ export const spawnNearby = (world, tmplt, x, y, z) => {
       placeOnMap(world, e, x1, y1, z);
       placed = true;
     }
-    if (++retry > 8) {
+    if (++retry > 16) {
       retry = 0;
       ++r;
     }

+ 8 - 2
src/routes/djii/mission.ts

@@ -15,9 +15,14 @@ export const Mission = defineComponent('Mission', {
   template: [Types.ui8, 32],
 });
 
-const missionTemplates = new Map();
+type MissionTemplate = {
+  generate: (world: IWorld, floorCount: number, minSize: number, maxSize: number) => [number, number, number],
+  onEntrance: (world: IWorld, pc: Entity) => void,
+};
+
+const missionTemplates = new Map<string, MissionTemplate>();
 
-export const registerMissionTemplate = (name: string, tmplt) => {
+export const registerMissionTemplate = (name: string, tmplt: MissionTemplate) => {
   missionTemplates.set(name, tmplt);
 };
 
@@ -50,4 +55,5 @@ const prepareMission = (world, mission, pc) => {
   }
   const [x, y, z] = tmplt.generate(world, floorCount);
   placeOnMap(world, pc, x, y, z);
+  tmplt.onEntrance(world, pc);
 };

+ 0 - 0
src/routes/djii/skill.ts


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff