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