]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/monsters/monster/enforcer.qc
Big load of updates (attempted CSQC monsters)
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / monsters / monster / enforcer.qc
1 #ifndef MENUQC
2 // size
3 const vector ENFORCER_MIN = '-32 -32 0';
4 const vector ENFORCER_MAX = '32 32 64';
5
6 // model
7 string ENFORCER_MODEL = "models/turrets/ewheel-base2.md3";
8
9 #endif
10
11 #ifdef SVQC
12 // cvars
13 float autocvar_g_monster_enforcer;
14 float autocvar_g_monster_enforcer_health;
15 float autocvar_g_monster_enforcer_speed_walk;
16 float autocvar_g_monster_enforcer_speed_run;
17 float autocvar_g_monster_enforcer_attack_uzi_bullets;
18
19 // animations
20 const float enforcer_anim_stop          = 0;
21 const float enforcer_anim_walk          = 1;
22 const float enforcer_anim_run           = 2;
23 const float enforcer_anim_walkback      = 3;
24 const float enforcer_anim_runback       = 4;
25
26 void enforcer_think ()
27 {
28         self.think = enforcer_think;
29         self.nextthink = time + self.ticrate;
30         
31         if(self.delay != -1)
32                 self.nextthink = self.delay;
33         
34         monster_move(autocvar_g_monster_enforcer_speed_run, autocvar_g_monster_enforcer_speed_walk, 100, enforcer_anim_run, enforcer_anim_walk, enforcer_anim_stop);
35 }
36
37 .float enf_cycles;
38 void enforcer_uzi_fire ()
39 {
40         self.enf_cycles += 1;
41         
42         if(self.enf_cycles > autocvar_g_monster_enforcer_attack_uzi_bullets)
43         {
44                 self.monster_delayedattack = func_null;
45                 self.delay = -1;
46                 return;
47         }
48         W_UZI_Attack(DEATH_MONSTER_ENFORCER);
49         self.delay = time + 0.1;
50         self.monster_delayedattack = enforcer_uzi_fire;
51 }
52
53 float enforcer_attack()
54 {
55         makevectors(self.angles);
56         switch(self.weapon)
57         {
58                 case WEP_ROCKET_LAUNCHER:
59                 {
60                         self.attack_finished_single = time + 0.8;
61                         W_Rocket_Attack();
62                         return TRUE;
63                 }
64                 case WEP_ELECTRO:
65                 {
66                         self.attack_finished_single = time + 0.8;
67                         W_Electro_Attack();
68                         return TRUE;
69                 }
70                 case WEP_SHOTGUN:
71                 {
72                         self.attack_finished_single = time + 0.8;
73                         W_Shotgun_Attack();
74                         return TRUE;
75                 }
76                 case WEP_UZI:
77                 {
78                         self.enf_cycles = 0;
79                         self.attack_finished_single = time + 0.8;
80                         self.delay = time + 0.1;
81                         self.monster_delayedattack = enforcer_uzi_fire;
82                         return TRUE;
83                 }
84                 case WEP_LASER:
85                 {
86                         self.attack_finished_single = time + 0.8;
87                         W_Laser_Attack(0);
88                 }
89                 default:
90                         return FALSE; // no weapon?
91         }
92         
93         // never gets here
94 }
95
96 void enforcer_die ()
97 {
98         Monster_CheckDropCvars ("enforcer");
99         
100         self.think = Monster_Fade;
101         self.nextthink = time + 5;
102         monsters_setframe(enforcer_anim_stop);
103                 
104         monster_hook_death(); // for post-death mods
105 }
106
107 void enforcer_spawn ()
108 {
109         if not(self.health)
110                 self.health = autocvar_g_monster_enforcer_health * self.scale;
111
112         self.damageforcescale   = 0;
113         self.classname                  = "monster_enforcer";
114         self.checkattack                = GenericCheckAttack;
115         self.nextthink                  = time + random() * 0.5 + 0.1;
116         self.think                              = enforcer_think;
117         self.items                              = (IT_SHELLS | IT_ROCKETS | IT_NAILS | IT_CELLS);
118         self.sprite_height              = 45;
119         self.attack_ranged              = enforcer_attack;
120         self.view_ofs              *= 0.5;
121         
122         self.weaponentity = spawn();
123         self.weaponentity.owner = self;
124         self.weaponentity.team = self.team;
125         self.weaponentity.solid = SOLID_NOT;
126         self.weaponentity.owner = self.weaponentity.realowner = self;
127         self.weaponentity.movetype = MOVETYPE_NOCLIP;
128         setmodel(self.weaponentity, "models/turrets/ewheel-gun1.md3");
129         setattachment(self.weaponentity, self, "tag_head");
130         
131         RandomSelection_Init();
132         RandomSelection_Add(world, WEP_ROCKET_LAUNCHER, "", 1, 1);
133         RandomSelection_Add(world, WEP_ELECTRO, "", 1, 1);
134         RandomSelection_Add(world, WEP_SHOTGUN, "", 1, 1);
135         RandomSelection_Add(world, WEP_UZI, "", 1, 1);
136         RandomSelection_Add(world, WEP_LASER, "", 1, 1);
137         
138         self.weapon = RandomSelection_chosen_float;
139                 
140         monster_hook_spawn(); // for post-spawn mods
141 }
142
143 void spawnfunc_monster_enforcer ()
144 {       
145         if not(autocvar_g_monster_enforcer) { remove(self); return; }
146         
147         self.monster_spawnfunc = spawnfunc_monster_enforcer;
148         
149         if(Monster_CheckAppearFlags(self))
150                 return;
151         
152         if not (monster_initialize(
153                          "Enforcer", MONSTER_ENFORCER,
154                          ENFORCER_MODEL,
155                          ENFORCER_MIN, ENFORCER_MAX,
156                          FALSE,
157                          enforcer_die, enforcer_spawn))
158         {
159                 remove(self);
160                 return;
161         }
162 }
163
164 #endif // SVQC