]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/monsters/monster/zombie.qc
d698b4a731124e50144251a7ad1afce6e6f539dd
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / monsters / monster / zombie.qc
1 #ifdef REGISTER_MONSTER
2 REGISTER_MONSTER(
3 /* MON_##id   */ ZOMBIE,
4 /* function   */ m_zombie,
5 /* spawnflags */ 0,
6 /* mins,maxs  */ '-18 -18 -25', '18 18 47',
7 /* model      */ "zombie.dpm",
8 /* netname    */ "zombie",
9 /* fullname   */ _("Zombie")
10 );
11
12 #define ZOMBIE_SETTINGS(monster) \
13         MON_ADD_CVAR(monster, health) \
14         MON_ADD_CVAR(monster, attack_melee_damage) \
15         MON_ADD_CVAR(monster, attack_melee_delay) \
16         MON_ADD_CVAR(monster, attack_leap_damage) \
17         MON_ADD_CVAR(monster, attack_leap_force) \
18         MON_ADD_CVAR(monster, attack_leap_speed) \
19         MON_ADD_CVAR(monster, attack_leap_delay) \
20         MON_ADD_CVAR(monster, speed_stop) \
21         MON_ADD_CVAR(monster, speed_run) \
22         MON_ADD_CVAR(monster, speed_walk) 
23
24 #ifdef SVQC
25 ZOMBIE_SETTINGS(zombie)
26 #endif // SVQC
27 #else
28 #ifdef SVQC
29 const float zombie_anim_attackleap                      = 0;
30 const float zombie_anim_attackrun1                      = 1;
31 const float zombie_anim_attackrun2                      = 2;
32 const float zombie_anim_attackrun3                      = 3;
33 const float zombie_anim_attackstanding1         = 4;
34 const float zombie_anim_attackstanding2         = 5;
35 const float zombie_anim_attackstanding3         = 6;
36 const float zombie_anim_blockend                        = 7;
37 const float zombie_anim_blockstart                      = 8;
38 const float zombie_anim_deathback1                      = 9;
39 const float zombie_anim_deathback2                      = 10;
40 const float zombie_anim_deathback3                      = 11;
41 const float zombie_anim_deathfront1                     = 12;
42 const float zombie_anim_deathfront2                     = 13;
43 const float zombie_anim_deathfront3                     = 14;
44 const float zombie_anim_deathleft1                      = 15;
45 const float zombie_anim_deathleft2                      = 16;
46 const float zombie_anim_deathright1                     = 17;
47 const float zombie_anim_deathright2                     = 18;
48 const float zombie_anim_idle                            = 19;
49 const float zombie_anim_painback1                       = 20;
50 const float zombie_anim_painback2                       = 21;
51 const float zombie_anim_painfront1                      = 22;
52 const float zombie_anim_painfront2                      = 23;
53 const float zombie_anim_runbackwards            = 24;
54 const float zombie_anim_runbackwardsleft        = 25;
55 const float zombie_anim_runbackwardsright       = 26;
56 const float zombie_anim_runforward                      = 27;
57 const float zombie_anim_runforwardleft          = 28;
58 const float zombie_anim_runforwardright         = 29;
59 const float zombie_anim_spawn                           = 30;
60
61 void zombie_attack_leap_touch()
62 {
63         if (self.health <= 0)
64                 return;
65                 
66         vector angles_face;
67
68         if(other.takedamage)
69         {
70                 angles_face = vectoangles(self.moveto - self.origin);
71                 angles_face = normalize(angles_face) * MON_CVAR(zombie, attack_leap_force);
72                 Damage(other, self, self, MON_CVAR(zombie, attack_leap_damage) * monster_skill, DEATH_MONSTER_ZOMBIE_JUMP, other.origin, angles_face);
73                 self.touch = MonsterTouch; // instantly turn it off to stop damage spam
74         }
75
76         if (trace_dphitcontents)
77                 self.touch = MonsterTouch;
78 }
79
80 float zombie_attack(float attack_type)
81 {
82         switch(attack_type)
83         {
84                 case MONSTER_ATTACK_MELEE:
85                 {
86                         float rand = random(), chosen_anim;
87                 
88                         if(rand < 0.33)
89                                 chosen_anim = zombie_anim_attackstanding1;
90                         else if(rand < 0.66)
91                                 chosen_anim = zombie_anim_attackstanding2;
92                         else
93                                 chosen_anim = zombie_anim_attackstanding3;
94                                 
95                         monsters_setframe(chosen_anim);
96
97                         self.attack_finished_single = time + MON_CVAR(zombie, attack_melee_delay);
98                         
99                         monster_melee(self.enemy, MON_CVAR(zombie, attack_melee_damage), 0.3, DEATH_MONSTER_ZOMBIE_MELEE, TRUE);
100                         
101                         return TRUE;
102                 }
103                 case MONSTER_ATTACK_RANGED:
104                 {
105                         makevectors(self.angles);
106                         if(monster_leap(zombie_anim_attackleap, zombie_attack_leap_touch, v_forward * MON_CVAR(zombie, attack_leap_speed) + '0 0 200', MON_CVAR(zombie, attack_leap_delay)))
107                                 return TRUE;
108                 }
109         }
110         
111         return FALSE;
112 }
113
114 void spawnfunc_monster_zombie() 
115 {
116         self.classname = "monster_zombie";
117         
118         self.monster_spawnfunc = spawnfunc_monster_zombie;
119         
120         self.spawnflags |= MONSTER_RESPAWN_DEATHPOINT;
121         
122         if(Monster_CheckAppearFlags(self))
123                 return;
124         
125         if not(monster_initialize(MON_ZOMBIE, FALSE)) { remove(self); return; }
126 }
127
128 float m_zombie(float req)
129 {
130         switch(req)
131         {
132                 case MR_THINK:
133                 {
134                         monster_move(MON_CVAR(zombie, speed_run), MON_CVAR(zombie, speed_walk), MON_CVAR(zombie, speed_stop), zombie_anim_runforward, zombie_anim_runforward, zombie_anim_idle);
135                         return TRUE;
136                 }
137                 case MR_DEATH:
138                 {
139                         monsters_setframe((random() > 0.5) ? zombie_anim_deathback1 : zombie_anim_deathfront1);
140                         return TRUE;
141                 }
142                 case MR_SETUP:
143                 {
144                         if not(self.health) self.health = MON_CVAR(zombie, health);
145                                 
146                         self.monster_attackfunc = zombie_attack;
147                         monsters_setframe(zombie_anim_spawn);
148                         self.spawn_time = time + 2.1;
149                         self.spawnshieldtime = self.spawn_time;
150                         self.respawntime = 0.1;
151                         
152                         return TRUE;
153                 }
154                 case MR_INIT:
155                 {
156                         // nothing
157                         return TRUE;
158                 }
159                 case MR_CONFIG:
160                 {
161                         MON_CONFIG_SETTINGS(ZOMBIE_SETTINGS(zombie))
162                         return TRUE;
163                 }
164         }
165         
166         return TRUE;
167 }
168
169 #endif // SVQC
170 #ifdef CSQC
171 float m_zombie(float req)
172 {
173         switch(req)
174         {
175                 case MR_DEATH:
176                 {
177                         // nothing
178                         return TRUE;
179                 }
180                 case MR_INIT:
181                 {
182                         precache_model ("models/monsters/zombie.dpm");
183                         return TRUE;
184                 }
185         }
186         
187         return TRUE;
188 }
189
190 #endif // CSQC
191 #endif // REGISTER_MONSTER