DEADSOFTWARE

New zomby brain!
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Thu, 7 Sep 2017 19:34:03 +0000 (22:34 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Thu, 7 Sep 2017 19:34:03 +0000 (22:34 +0300)
BUGS
src/items.mpsrc
src/mobs.pas

diff --git a/BUGS b/BUGS
index bdb696b6e183d8314adbe5f7a90d67b0bbc1bf81..a3ecce904a5d4aeeef0c830f7807080da6d2c860 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -5,6 +5,15 @@
 + Выпадение за карту после загрузки мира
 + Ломаются кактусы и снег на старте игры
 Реализованы не все мобы которые были
+  + Зомби
+    Курица
+    Корова
+    Гриная корова
+    Крипер
+    Свинья
+    Пигмен
+    Овца
+    Паук
 Зомби не может номально выпрыгнуть из воды
 Мобы не дохнут от солнечного света
 + Убогая текстура дождя
 + Печи и мобы не сохраняются и не загружаются (не забыть инкрементировать версию формата карт)
 При создании мира с сундуком, оный может висеть в воздухе
 + Зависание при попытке листать пустой список сохранений
-Иногда вместо травы генерируется грязь.
-Перепроверить генерацию предметов в вокровищницах
+Иногда вместо травы генерируется грязь. (баг или фича - хз)
+Перепроверить генерацию предметов в cокровищницах
 Починить спавнеры
 + Уголь встречается на поверхности реже чем железо
-Починит установку блока при прыжке
+Починить установку блока при прыжке
 Перепроверить рост деревьев
 + Печь не светится когда работает
 * Потеря контрастности при малом количестве источников света 
index 3c84b8dab7a5c310f7f9921a2de783deff16fd08..d1b914a6321c42d0fc2a92f2e68456a1d839b98b 100644 (file)
@@ -9,6 +9,9 @@ interface
   ITEM_FLAG_IND2=2;\r
   ITEM_FLAG_DIV=4;\r
   ITEM_FLAG_TEX=8;\r
+\r
+  rottenMeat = 190;\r
+\r
  var\r
   compas:image;\r
   clock:array[0..7] of image;\r
index ebe716ec6a230821de4088db8ef6cbb264ee0d68..c255d0ea2f265ad7b19bdcce60a44c70452e5b48 100644 (file)
@@ -26,17 +26,22 @@ interface
 \r
 implementation\r
 \r
-  uses phy, player, canvas, jsr75i, func;\r
+  uses phy, player, canvas, jsr75i, func, drop, items;\r
 \r
   const\r
     lastType = 1;\r
     lastMob = 31;\r
+    lastZombyFrame = 11;\r
 \r
   var\r
-    mtype, mx, my, mvx, mvy, mpos, mhp : array [0..lastMob] of integer;\r
+    mtype, mx, my, mvx, mvy, mpos, mhp, ma, mb, mc : array [0..lastMob] of integer;\r
     mjump : array [0..lastMob] of boolean;\r
     tw, th, thp, tjump : array [none..lastType] of integer;\r
 \r
+    zombyBody : array [0..1] of image;\r
+    zombyLegs : array [0..1, 0..2] of image;\r
+    zombyAnim : array [0..lastZombyFrame] of integer;\r
+\r
   procedure UseObject(i : integer);\r
     begin\r
       Phy.LoadObject(mx[i], my[i], tw[mtype[i]], th[mtype[i]], mvx[i], mvy[i], mjump[i]);\r
@@ -51,12 +56,13 @@ implementation
       mjump[i] := Phy.GetJmp;\r
     end;\r
 \r
-  procedure InitTab(typ, w, h, hp : integer);\r
+  procedure InitTab(typ, w, h, hp, jump : integer);\r
     begin\r
       assert((typ >= 0) and (typ <= lastType));\r
       tw[typ] := w;\r
       th[typ] := h;\r
       thp[typ] := hp;\r
+      tjump[typ] := jump;\r
     end;\r
 \r
   function GetW(i : integer) : integer;\r
@@ -79,15 +85,29 @@ implementation
       result := tjump[mtype[i]];\r
     end;\r
 \r
-  procedure Jump(i : integer);\r
+  function IsSolidStep(i, vec : integer) : boolean;\r
+    var\r
+      x, y : integer;\r
     begin\r
-      UseObject(i);\r
-      Phy.JumpObj(GetJumpHeight(i));\r
-      UpdateObject(i);\r
+      if vec < 0 then x := (mx[i] - 8) / 16;\r
+      else if vec > 0 then x := (mx[i] + GetW(i) + 4) / 16;\r
+      else x := (mx[i] + GetW(i) / 2) / 16;\r
+      y := (my[i] + GetH(i) - 8) / 16;\r
+      result := Phy.IsSolid(x, y, mvx[i] + vec, mvy[i]);\r
+    end;\r
+\r
+  procedure Swim(i, vec : integer);\r
+    begin\r
+      if Phy.MapCollType(50, mx[i], my[i], GetW(i), GetH(i) / 2) or\r
+         Phy.MapCollType(51, mx[i], my[i], GetW(i), GetH(i) / 2)\r
+      then begin\r
+        if (vec <> 0) and IsSolidStep(i, vec) then mvy[i] := -10 else mvy[i] := -2;\r
+      end;\r
     end;\r
 \r
   procedure Step(i, vec : integer);\r
     begin\r
+      Swim(i, vec);\r
       if vec < 0 then\r
         begin\r
           mvx[i] := mvx[i] + vec;\r
@@ -100,14 +120,11 @@ implementation
         end;\r
     end;\r
 \r
-  function IsSolidStep(i, vec : integer) : boolean;\r
-    var\r
-      x, y : integer;\r
+  procedure Jump(i, vec : integer);\r
     begin\r
-      if vec > 0 then x := (mx[i] + GetW(i) / 2 + 16 / 2) / 16;\r
-      else x := (mx[i] + GetW(i) / 2 - 16 / 2) / 16;\r
-      y := (my[i] + GetH(i)) / 16 - 1;\r
-      result := Phy.IsSolid(x, y, mvx[i], mvy[i]);\r
+      UseObject(i);\r
+      Phy.JumpObj(GetJumpHeight(i));\r
+      UpdateObject(i);\r
     end;\r
 \r
   function CollisionWithPlayer(i : integer) : boolean;\r
@@ -118,6 +135,111 @@ implementation
       );\r
     end;\r
 \r
+  procedure Die(i : integer);\r
+    var\r
+      x, y : integer;\r
+    begin\r
+      x := mx[i] + GetW(i) / 2;\r
+      y := my[i] + GetH(i) / 2;\r
+      if mtype[i] = zomby then\r
+        begin\r
+          Drop.Create(Items.rottenMeat, x, y, Random(3));\r
+        end;\r
+      mtype[i] := none;\r
+    end;\r
+\r
+  procedure Hit(i, damage : integer);\r
+    begin\r
+      mhp[i] := mhp[i] - damage;\r
+      if mhp[i] <= 0 then Die(i);\r
+    end;\r
+\r
+  (** ZombyThink -- мозги зомби **)\r
+  (**  ma = Кадр анимации       **)\r
+  (**  mb = Таймер действий     **)\r
+  (**  mc = Состояние           **)\r
+\r
+  procedure ZombyThink(i : integer);\r
+    const\r
+      stay = 0;\r
+      walkleft = 1;\r
+      walkright = 2;\r
+      angry = 3;\r
+    const\r
+      bite = 1;\r
+      speed = 1;\r
+      walkTime = 30;\r
+      angryTime = 200;\r
+      stayTime = 300;\r
+    begin\r
+      // Debug('state: ' + mc[i] + ' / anim ' + ma[i] + ' / ticks ' + mb[i]);\r
+\r
+      mb[i] := mb[i] - 1;\r
+      if mb[i] < 0 then mb[i] := 0;\r
+      if CollisionWithPlayer(i) then Player.BiteIt(bite, mvx[i]);\r
+\r
+      (* Вижу игрока - сразу агрюсь и бегу за ним некоторое время *)\r
+      if (mpos[i] = 0) and (Player.GetX - mx[i] < 0) or (mpos[i] = 1) and (Player.GetX - mx[i] > 0) then\r
+        if Phy.CanSeeObj(mx[i], my[i], Player.GetX, Player.GetY) then\r
+          begin\r
+            mb[i] := angryTime;\r
+            mc[i] := angry;\r
+          end;\r
+\r
+      if mc[i] = stay then begin\r
+        ma[i] := 0;\r
+        Swim(i, 0);\r
+        if (mb[i] <= 0) and (Random(100) <= 2) then\r
+          begin\r
+            mb[i] := walkTime + Random(walkTime);\r
+            mc[i] := walkleft + Random(2); (* Случайный разворот *)\r
+          end;\r
+      end else if mc[i] = walkleft then begin\r
+        if IsSolidStep(i, -speed) then Jump(i, -speed);\r
+        Step(i, -speed);\r
+        ma[i] := (ma[i] + 1) mod lastZombyFrame;\r
+        if mb[i] <= 0 then mc[i] := stay;\r
+      end else if mc[i] = walkright then begin\r
+        if IsSolidStep(i, speed) then Jump(i, speed);\r
+        Step(i, speed);\r
+        ma[i] := (ma[i] + 1) mod lastZombyFrame;\r
+        if mb[i] <= 0 then mc[i] := stay;\r
+      end else if mc[i] = angry then begin\r
+        if mb[i] <= 0 then begin\r
+          if Phy.CanSeeObj(mx[i], my[i], Player.GetX, Player.GetY) then begin\r
+            (* Видижу игрока - устанавливаю время преследования *)\r
+            mb[i] := angryTime;\r
+          end else begin\r
+            (* Игрока давно не было видно - ждём его некоторое время на месте *)\r
+            mb[i] := stayTime;\r
+            mc[i] := stay;\r
+          end;\r
+        end else begin\r
+          (* Бежим за игроком  *)\r
+          if Player.GetX - mx[i] < 4 then begin\r
+            if IsSolidStep(i, -speed) then Jump(i, -speed);\r
+            Step(i, -speed);\r
+            ma[i] := (ma[i] + 1) mod lastZombyFrame;\r
+          end else if Player.GetX - mx[i] > 4 then begin\r
+            if IsSolidStep(i, speed) then Jump(i, speed);\r
+            Step(i, speed);\r
+            ma[i] := (ma[i] + 1) mod lastZombyFrame;\r
+          end else begin\r
+            Swim(i, 0);\r
+          end;\r
+        end;\r
+      end;\r
+    end;\r
+\r
+  procedure ZombyDraw(i, camx, camy : integer);\r
+    var\r
+      frame : integer;\r
+    begin\r
+      frame := zombyAnim[ma[i]];\r
+      DrawImage(zombyBody[mpos[i]], mx[i] - 6 - camx, my[i] - camy);\r
+      DrawImage(zombyLegs[mpos[i], frame], mx[i] - 2 - camx, my[i] + 20 - camy);\r
+    end;\r
+\r
 (* ============= Public ============= *)\r
 \r
   procedure Create(typ, x, y : integer);\r
@@ -136,36 +258,41 @@ implementation
           mpos[i] := 0;\r
           mhp[i] := thp[typ];\r
           mjump[i] := false;\r
+          ma[i] := 0;\r
+          mb[i] := 0;\r
+          mc[i] := 0;\r
           debug('Created mob is ' + i);\r
           exit;\r
         end;\r
       Debug('Mob type ' + typ + ' not created');\r
     end;\r
 \r
-  function FindAndHit(value, x, y, w, h, addvx, addvy : integer) : integer;\r
+  function FindAndHit(damage, x, y, w, h, addvx, addvy : integer) : integer;\r
     var\r
       i : integer;\r
     begin\r
-(*\r
-      for i:=0 to MAX_MOBS do\r
-        if getType(i)<>M_NONE then\r
-          if CollTwoObj(x, y, w, h, wx[i], wy[i], GetW(i), GetH(i)) then\r
-            begin\r
-              setVX(getVX(i) + addvx, i);\r
-              setVX(getVY(i) + addvy, i);\r
-              hit(value, i);\r
-              findAndHit := i;\r
-              exit;\r
-            end;\r
-*)\r
-     findAndHit := -1;\r
-   end;\r
+      for i := 0 to lastMob do if mtype[i] <> none then\r
+        if CollTwoObj(x, y, w, h, mx[i], my[i], GetW(i), GetH(i)) then\r
+          begin\r
+            mvx[i] := mvx[i] + addvx;\r
+            mvy[i] := mvy[i] + addvy;\r
+            Hit(i,  damage);\r
+            FindAndHit := i;\r
+            exit;\r
+          end;\r
+      FindAndHit := -1;\r
+    end;\r
 \r
   procedure Update;\r
     var\r
-      i : integer;\r
+      i, typ : integer;\r
     begin\r
-      (* TODO *)\r
+      for i := 0 to lastMob do if mtype[i] <> none then\r
+        begin\r
+          typ := mtype[i];\r
+          if typ = zomby then ZombyThink(i);\r
+          if mhp[i] <= 0 then Die(i);\r
+        end;\r
     end;\r
 \r
   procedure UpdatePhy;\r
@@ -182,28 +309,42 @@ implementation
 \r
   procedure Draw(camx, camy:integer);\r
     var\r
-      i : integer;\r
+      i, typ : integer;\r
     begin\r
       for i := 0 to lastMob do if mtype[i] <> none then\r
         begin\r
-          SetColor(0, 0, 255);\r
-          FillRect(mx[i] - camx, my[i] - camy, GetW(i), GetH(i));\r
+          typ := mtype[i];\r
+          if typ = zomby then ZombyDraw(i, camx, camy);\r
+          //SetColor(0, 0, 255);\r
+          //DrawRect(mx[i] - camx, my[i] - camy, GetW(i) - 1, GetH(i) - 1);\r
         end;\r
     end;\r
 \r
   procedure LoadTextures(path : string);\r
     var\r
-      im:image;\r
+      im : image;\r
     begin\r
-      // im:=ld_tex('zombie_ani.png', path, 'mobs/');\r
+      im := ld_tex('zombie_ani.png', path, 'mobs/');\r
+      zombyBody[0] := rotate_image_from_image(im, 0, 0, 20, 22, 0);\r
+      zombyBody[1] := rotate_image_from_image(im, 21, 0, 20, 22, 0);\r
+      zombyLegs[0, 0] := rotate_image_from_image(im, 0, 52, 12, 12, 0);\r
+      zombyLegs[0, 1] := rotate_image_from_image(im, 13, 52, 12, 12, 0);\r
+      zombyLegs[0, 2] := rotate_image_from_image(im, 26, 52, 12, 12, 0);\r
+      zombyLegs[1, 0] := rotate_image_from_image(im, 39, 52, 12, 12, 0);\r
+      zombyLegs[1, 1] := rotate_image_from_image(im, 52, 52, 12, 12, 0);\r
+      zombyLegs[1, 2] := rotate_image_from_image(im, 65, 52, 12, 12, 0);\r
     end;\r
 \r
-  procedure FreeTextures;//Выгрузка текстур\r
+  procedure FreeTextures;\r
     var\r
-      i : integer;\r
+      i, j : integer;\r
       nullimg : image;\r
     begin\r
-      (* TODO *)\r
+      for i := 0 to 1 do\r
+        begin\r
+          zombyBody[i] := nullimg;\r
+          for j := 0 to 2 do zombyLegs[i, j] := nullimg;\r
+        end;\r
     end;\r
 \r
   procedure SaveData;\r
@@ -220,6 +361,9 @@ implementation
           write_byte(mpos[i]);\r
           writeint(mhp[i]);\r
           writebool(mjump[i]);\r
+          writeint(ma[i]);\r
+          writeint(mb[i]);\r
+          writeint(mc[i]);\r
         end;\r
    end;\r
 \r
@@ -237,6 +381,9 @@ implementation
           mpos[i] := read_byte;\r
           mhp[i] := readint;\r
           mjump[i] := readbool;\r
+          ma[i] := readint;\r
+          mb[i] := readint;\r
+          mc[i] := readint;\r
         end;\r
    end;\r
 \r
@@ -254,10 +401,26 @@ implementation
           mpos[i] := 0;\r
           mhp[i] := 0;\r
           mjump[i] := false;\r
+          ma[i] := 0;\r
+          mb[i] := 0;\r
+          mc[i] := 0;\r
         end;\r
    end;\r
 \r
 initialization\r
-  InitTab(none, 0, 0, 0);\r
-  InitTab(zomby, 8, 32, 10);\r
+  InitTab(none, 0, 0, 0, 0);\r
+  InitTab(zomby, 8, 32, 10, 7);\r
+\r
+  zombyAnim[0] := 0;\r
+  zombyAnim[1] := 0;\r
+  zombyAnim[2] := 0;\r
+  zombyAnim[3] := 1;\r
+  zombyAnim[4] := 1;\r
+  zombyAnim[5] := 1;\r
+  zombyAnim[6] := 2;\r
+  zombyAnim[7] := 2;\r
+  zombyAnim[8] := 2;\r
+  zombyAnim[9] := 1;\r
+  zombyAnim[10] := 1;\r
+  zombyAnim[11] := 1;\r
 end.\r