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