thrown enemies now does damage
[k8vacspelynky.git] / mapent / enemies / zombie.vc
blobfce701b14a63699363f656ce275336c36297f51c
1 /**********************************************************************************
2  * Copyright (c) 2008, 2009 Derek Yu and Mossmouth, LLC
3  * Copyright (c) 2018, Ketmar Dark
4  *
5  * This file is part of Spelunky.
6  *
7  * You can redistribute and/or modify Spelunky, including its source code, under
8  * the terms of the Spelunky User License.
9  *
10  * Spelunky is distributed in the hope that it will be entertaining and useful,
11  * but WITHOUT WARRANTY.  Please see the Spelunky User License for more details.
12  *
13  * The Spelunky User License should be available in "Game Information", which
14  * can be found in the Resource Explorer, or as an external file called COPYING.
15  * If not, please obtain a new copy of Spelunky from <http://spelunkyworld.com/>
16  *
17  **********************************************************************************/
18 class EnemyZombie['oZombie'] : MapEnemy;
21 IDLE = 0;
22 BOUNCE = 1;
23 RECOVER = 2;
24 WALK = 3;
25 DROWNED = 4;
28 //int bounceCounter;
30 override bool initialize () {
31   if (!::initialize()) return false;
32   setSprite('sZombieLeft');
33   dir = global.randOther(0, 1);
34   if (level.isWaterAtPoint(ix, iy)) swimming = true;
35   return true;
40 override void onAnimationLooped () {
41   if (spriteLName == spriteFlipName) setSprite(spriteNormalName);
46 override void thinkFrame () {
47   ::thinkFrame();
48   if (!isInstanceAlive) return;
50   moveRel(xVel, yVel);
52   yVel = fmin(yVel+myGrav, yVelLimit);
54   int x = ix, y = iy;
56   if (level.isSolidAtPoint(x+8, y+8)) hp = -999;
58   if (hp < 1) {
59     spillBlood();
60     foreach (; 0..3) level.MakeMapObject(ix+8, iy+8, 'oBone');
61     auto skull = level.MakeMapObject(ix+8, iy+8, 'oSkull');
62     if (skull) {
63       skull.yVel = -global.randOther(1, 3);
64       skull.xVel = global.randOther(0, 3)-global.randOther(0, 3);
65     }
66     if (countsAsKill) level.addKill(objName);
67     instanceRemove();
68     return;
69   }
71   if (isCollisionRight(1)) xVel = -1;
72   if (isCollisionLeft(1)) xVel = 1;
74   bool colBot = !!isCollisionBottom(1);
76   if (status == IDLE) {
77     auto dist = distanceToEntityCenter(level.player);
78     xVel = 0;
79          if (counter > 0) --counter;
80     else if (dist < 64) status = BOUNCE;
81     if (dist < 48) status = BOUNCE;
82     if (level.player.swimming) status = IDLE;
83     if (status == BOUNCE) playSound('sndZombie');
84   } else if (status == RECOVER) {
85     if (colBot) {
86       status = IDLE;
87       xVel = 0;
88       yVel = 0;
89       counter = global.randOther(40, 100);
90     }
91   } else if (status == BOUNCE) {
92     if (colBot) {
93       if (global.randOther(1, 4) == 1) {
94         yVel = -global.randOther(2, 4);
95         if (level.player.ix < x) { dir = Dir.Left; xVel = -3; } else { dir = Dir.Right; xVel = 3; }
96       } else {
97         yVel = -global.randOther(1, 2);
98         if (level.player.ix < x) { dir = Dir.Left; xVel = -1; } else { dir = Dir.Right; xVel = 1; }
99       }
100     } else {
101       status = RECOVER;
102     }
103   } else if (status != DROWNED) {
104     status = IDLE;
105     xVel = 0;
106   }
108   if (isCollisionTop(1)) yVel = 1;
110   //if (isCollisionSolid()) y -= 2;
112   setSprite(!colBot ? 'sZombieJumpL' : 'sZombieLeft');
116 defaultproperties {
117   objName = 'Zombie';
118   desc = "Jiang Shi";
119   desc2 = "A well-dressed, territorial corpse, inhabited by a restless spirit.";
120   status = IDLE;
122   setCollisionBounds(0, 2, 16, 16);
124   xVel = 0;
125   yVel = 0;
126   yDelta = -0.4;
127   myGrav = 0.2;
128   myGravNorm = 0.2;
129   imageSpeed = 0.4;
131   doBasicPhysics = false;
132   flying = false; // don't fall
134   // stats
135   hp = 1;
136   invincible = 0;
138   bloodless = true;
139   bounced = false;
140   dead = false;
141   counter = 20;
142   countsAsKill = true;
143   leavesBody = true; // we will do our own death sequence
145   counter = 0;
146   //bounceCounter = 0;
148   depth = 40;