]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/monsters/monster/spider.qc
Merge branch 'master' into TimePath/global_self
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / monsters / monster / spider.qc
1 #ifndef MENUQC
2 bool M_Spider(int);
3 #endif
4 REGISTER_MONSTER_SIMPLE(
5 /* MON_##id   */ SPIDER,
6 /* spawnflags */ MON_FLAG_MELEE | MON_FLAG_RANGED | MON_FLAG_RIDE,
7 /* mins,maxs  */ '-18 -18 -25', '18 18 30',
8 /* model      */ "spider.dpm",
9 /* netname    */ "spider",
10 /* fullname   */ _("Spider")
11 ) {
12 #ifndef MENUQC
13         this.monster_func = M_Spider;
14         this.monster_func(MR_PRECACHE);
15 #endif
16 }
17
18 #ifdef SVQC
19 float autocvar_g_monster_spider_health;
20 float autocvar_g_monster_spider_damageforcescale = 0.6;
21 float autocvar_g_monster_spider_attack_bite_damage;
22 float autocvar_g_monster_spider_attack_bite_delay;
23 float autocvar_g_monster_spider_attack_web_damagetime;
24 float autocvar_g_monster_spider_attack_web_speed;
25 float autocvar_g_monster_spider_attack_web_speed_up;
26 float autocvar_g_monster_spider_attack_web_delay;
27 float autocvar_g_monster_spider_speed_stop;
28 float autocvar_g_monster_spider_speed_run;
29 float autocvar_g_monster_spider_speed_walk;
30
31 /*
32 const float spider_anim_idle            = 0;
33 const float spider_anim_walk            = 1;
34 const float spider_anim_attack          = 2;
35 const float spider_anim_attack2         = 3;
36 */
37
38 .float spider_web_delay;
39
40 void M_Spider_Attack_Web_Explode()
41 {SELFPARAM();
42         entity e;
43         if(self)
44         {
45                 Send_Effect(EFFECT_ELECTRO_IMPACT, self.origin, '0 0 0', 1);
46                 RadiusDamage(self, self.realowner, 0, 0, 25, world, world, 25, self.projectiledeathtype, world);
47
48                 for(e = findradius(self.origin, 25); e; e = e.chain) if(e != self) if(e.takedamage && e.deadflag == DEAD_NO) if(e.health > 0) if(e.monsterid != MON_SPIDER.monsterid)
49                         e.spider_slowness = time + (autocvar_g_monster_spider_attack_web_damagetime);
50
51                 remove(self);
52         }
53 }
54
55 void M_Spider_Attack_Web_Touch()
56 {
57         PROJECTILE_TOUCH;
58
59         M_Spider_Attack_Web_Explode();
60 }
61
62 void M_Spider_Attack_Web()
63 {SELFPARAM();
64         monster_makevectors(self.enemy);
65
66         sound(self, CH_SHOTS, W_Sound("electro_fire2"), VOL_BASE, ATTEN_NORM);
67
68         entity proj = spawn ();
69         proj.classname = "plasma";
70         proj.owner = proj.realowner = self;
71         proj.use = M_Spider_Attack_Web_Explode;
72         proj.think = adaptor_think2use_hittype_splash;
73         proj.bot_dodge = true;
74         proj.bot_dodgerating = 0;
75         proj.nextthink = time + 5;
76         PROJECTILE_MAKETRIGGER(proj);
77         proj.projectiledeathtype = DEATH_MONSTER_SPIDER;
78         setorigin(proj, CENTER_OR_VIEWOFS(self));
79
80         //proj.glow_size = 50;
81         //proj.glow_color = 45;
82         proj.movetype = MOVETYPE_BOUNCE;
83         W_SetupProjVelocity_Explicit(proj, v_forward, v_up, (autocvar_g_monster_spider_attack_web_speed), (autocvar_g_monster_spider_attack_web_speed_up), 0, 0, false);
84         proj.touch = M_Spider_Attack_Web_Touch;
85         setsize(proj, '-4 -4 -4', '4 4 4');
86         proj.takedamage = DAMAGE_NO;
87         proj.damageforcescale = 0;
88         proj.health = 500;
89         proj.event_damage = func_null;
90         proj.flags = FL_PROJECTILE;
91         proj.damagedbycontents = true;
92
93         proj.bouncefactor = 0.3;
94         proj.bouncestop = 0.05;
95         proj.missile_flags = MIF_SPLASH | MIF_ARC;
96
97         CSQCProjectile(proj, true, PROJECTILE_ELECTRO, true);
98 }
99
100 bool M_Spider_Attack(int attack_type)
101 {SELFPARAM();
102         switch(attack_type)
103         {
104                 case MONSTER_ATTACK_MELEE:
105                 {
106                         return Monster_Attack_Melee(self.enemy, (autocvar_g_monster_spider_attack_bite_damage), ((random() > 0.5) ? self.anim_melee : self.anim_shoot), self.attack_range, (autocvar_g_monster_spider_attack_bite_delay), DEATH_MONSTER_SPIDER, true);
107                 }
108                 case MONSTER_ATTACK_RANGED:
109                 {
110                         if(time >= self.spider_web_delay)
111                         {
112                                 setanim(self, self.anim_shoot, true, true, true);
113                                 self.attack_finished_single = time + (autocvar_g_monster_spider_attack_web_delay);
114                                 self.anim_finished = time + 1;
115                                 M_Spider_Attack_Web();
116                                 self.spider_web_delay = time + 3;
117                                 return true;
118                         }
119
120                         return false;
121                 }
122         }
123
124         return false;
125 }
126
127 void spawnfunc_monster_spider() { Monster_Spawn(MON_SPIDER.monsterid); }
128 #endif // SVQC
129
130 bool M_Spider(int req)
131 {SELFPARAM();
132         switch(req)
133         {
134                 #ifdef SVQC
135                 case MR_THINK:
136                 {
137                         return true;
138                 }
139                 case MR_PAIN:
140                 {
141                         return true;
142                 }
143                 case MR_DEATH:
144                 {
145                         setanim(self, self.anim_melee, false, true, true);
146                         self.angles_x = 180;
147                         return true;
148                 }
149                 #endif
150                 #ifndef MENUQC
151                 case MR_ANIM:
152                 {
153                         vector none = '0 0 0';
154                         self.anim_walk = animfixfps(self, '1 1 1', none);
155                         self.anim_idle = animfixfps(self, '0 1 1', none);
156                         self.anim_melee = animfixfps(self, '2 1 5', none); // analyze models and set framerate
157                         self.anim_shoot = animfixfps(self, '3 1 5', none); // analyze models and set framerate
158                         self.anim_run = animfixfps(self, '1 1 1', none);
159
160                         return true;
161                 }
162                 #endif
163                 #ifdef SVQC
164                 case MR_SETUP:
165                 {
166                         if(!self.health) self.health = (autocvar_g_monster_spider_health);
167                         if(!self.speed) { self.speed = (autocvar_g_monster_spider_speed_walk); }
168                         if(!self.speed2) { self.speed2 = (autocvar_g_monster_spider_speed_run); }
169                         if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_spider_speed_stop); }
170                         if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_spider_damageforcescale); }
171
172                         self.monster_loot = spawnfunc_item_health_medium;
173                         self.monster_attackfunc = M_Spider_Attack;
174
175                         return true;
176                 }
177                 case MR_PRECACHE:
178                 {
179                         precache_model("models/monsters/spider.dpm");
180                         precache_sound (W_Sound("electro_fire2"));
181                         return true;
182                 }
183                 #endif
184         }
185
186         return true;
187 }