]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/monsters/monster/zombie.qc
Update zombie status while spawning
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / monsters / monster / zombie.qc
1 // size
2 const vector ZOMBIE_MIN = '-18 -18 -25';
3 const vector ZOMBIE_MAX = '18 18 47';
4
5 // model
6 string ZOMBIE_MODEL = "models/monsters/zombie.dpm";
7
8 #ifdef SVQC
9 // cvars
10 float autocvar_g_monster_zombie;
11 float autocvar_g_monster_zombie_stopspeed;
12 float autocvar_g_monster_zombie_attack_leap_damage;
13 float autocvar_g_monster_zombie_attack_leap_delay;
14 float autocvar_g_monster_zombie_attack_leap_force;
15 float autocvar_g_monster_zombie_attack_leap_speed;
16 float autocvar_g_monster_zombie_attack_stand_damage;
17 float autocvar_g_monster_zombie_attack_stand_delay;
18 float autocvar_g_monster_zombie_health;
19 float autocvar_g_monster_zombie_speed_walk;
20 float autocvar_g_monster_zombie_speed_run;
21
22 // animations
23 const float zombie_anim_attackleap                      = 0;
24 const float zombie_anim_attackrun1                      = 1;
25 const float zombie_anim_attackrun2                      = 2;
26 const float zombie_anim_attackrun3                      = 3;
27 const float zombie_anim_attackstanding1         = 4;
28 const float zombie_anim_attackstanding2         = 5;
29 const float zombie_anim_attackstanding3         = 6;
30 const float zombie_anim_blockend                        = 7;
31 const float zombie_anim_blockstart                      = 8;
32 const float zombie_anim_deathback1                      = 9;
33 const float zombie_anim_deathback2                      = 10;
34 const float zombie_anim_deathback3                      = 11;
35 const float zombie_anim_deathfront1                     = 12;
36 const float zombie_anim_deathfront2                     = 13;
37 const float zombie_anim_deathfront3                     = 14;
38 const float zombie_anim_deathleft1                      = 15;
39 const float zombie_anim_deathleft2                      = 16;
40 const float zombie_anim_deathright1                     = 17;
41 const float zombie_anim_deathright2                     = 18;
42 const float zombie_anim_idle                            = 19;
43 const float zombie_anim_painback1                       = 20;
44 const float zombie_anim_painback2                       = 21;
45 const float zombie_anim_painfront1                      = 22;
46 const float zombie_anim_painfront2                      = 23;
47 const float zombie_anim_runbackwards            = 24;
48 const float zombie_anim_runbackwardsleft        = 25;
49 const float zombie_anim_runbackwardsright       = 26;
50 const float zombie_anim_runforward                      = 27;
51 const float zombie_anim_runforwardleft          = 28;
52 const float zombie_anim_runforwardright         = 29;
53 const float zombie_anim_spawn                           = 30;
54
55 void zombie_attack_standing()
56 {
57         float rand = random(), chosen_anim;
58                 
59         if (rand < 0.33)
60                 chosen_anim = zombie_anim_attackstanding1;
61         else if (rand < 0.66)
62                 chosen_anim = zombie_anim_attackstanding2;
63         else
64                 chosen_anim = zombie_anim_attackstanding3;
65                 
66         monsters_setframe(chosen_anim);
67
68         self.attack_finished_single = time + autocvar_g_monster_zombie_attack_stand_delay;
69         
70         monster_melee(self.enemy, autocvar_g_monster_zombie_attack_stand_damage, 0.3, DEATH_MONSTER_ZOMBIE_MELEE, TRUE);
71 }
72
73 void zombie_attack_leap_touch ()
74 {
75         if (self.health <= 0)
76                 return;
77                 
78         vector angles_face;
79         float bigdmg = autocvar_g_monster_zombie_attack_leap_damage * self.scale;
80
81         if (monster_isvalidtarget(other, self))
82         {
83                 angles_face = vectoangles(self.moveto - self.origin);
84                 angles_face = normalize(angles_face) * autocvar_g_monster_zombie_attack_leap_force;
85                 Damage(other, self, self, bigdmg * monster_skill, DEATH_MONSTER_ZOMBIE_JUMP, other.origin, angles_face);
86                 self.touch = MonsterTouch; // instantly turn it off to stop damage spam
87         }
88
89         if(self.flags & FL_ONGROUND)
90                 self.touch = MonsterTouch;
91 }
92
93 float zombie_attack_ranged()
94 {
95         makevectors(self.angles);
96         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))
97                 return TRUE;
98                 
99         return FALSE;
100 }
101
102 void zombie_think()
103 {
104         self.think = zombie_think;
105         self.nextthink = time + self.ticrate;
106
107         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);
108 }
109
110 void zombie_die ()
111 {
112         Monster_CheckDropCvars ("zombie");
113         
114         self.think = monster_dead_think;
115         self.nextthink = time + self.ticrate;
116         self.ltime = time + 5;
117         monsters_setframe((random() > 0.5) ? zombie_anim_deathback1 : zombie_anim_deathfront1);
118                 
119         monster_hook_death(); // for post-death mods
120 }
121
122 void zombie_spawn() 
123 {
124         if not(self.health)
125                 self.health = autocvar_g_monster_zombie_health * self.scale;
126         
127         self.classname                  = "monster_zombie";
128         self.spawn_time                 = time + 2.1;
129         self.nextthink                  = time + random() * 0.5 + 0.1;
130         self.think                              = zombie_think;
131         self.checkattack                = GenericCheckAttack;
132         self.attack_melee               = zombie_attack_standing;
133         self.attack_ranged              = zombie_attack_ranged;
134         self.respawntime                = 0.1;
135         self.spawnflags            |= MONSTER_RESPAWN_DEATHPOINT; // always enabled for zombie
136         
137         monsters_setframe(zombie_anim_spawn);
138         
139         if not(self.monster_respawned)
140                 self.skin = rint(random() * 4);
141         
142         monster_setupsounds("zombie");
143         
144         monster_hook_spawn(); // for post-spawn mods
145 }
146
147 void spawnfunc_monster_zombie() 
148 {
149         if not(autocvar_g_monster_zombie) { remove(self); return; }
150         
151         self.monster_spawnfunc = spawnfunc_monster_zombie;
152         
153         if(Monster_CheckAppearFlags(self))
154                 return;
155         
156         if not (monster_initialize(
157                          "Zombie", MONSTER_ZOMBIE,
158                          ZOMBIE_MIN, ZOMBIE_MAX,
159                          FALSE,
160                          zombie_die, zombie_spawn))
161         {
162                 remove(self);
163                 return;
164         }
165 }
166
167 #endif //SVQC