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