Advertisement
Guest User

Untitled

a guest
May 19th, 2019
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.22 KB | None | 0 0
  1. // cvars
  2. float autocvar_g_monster_spider;
  3. float autocvar_g_monster_spider_stopspeed;
  4. float autocvar_g_monster_spider_attack_leap_delay;
  5. float autocvar_g_monster_spider_attack_leap_range;
  6. float autocvar_g_monster_spider_attack_stand_damage;
  7. float autocvar_g_monster_spider_attack_stand_delay;
  8. float autocvar_g_monster_spider_attack_stand_range;
  9. float autocvar_g_monster_spider_health;
  10. float autocvar_g_monster_spider_idle_timer_min;
  11. float autocvar_g_monster_spider_speed_walk;
  12. float autocvar_g_monster_spider_speed_run;
  13. float autocvar_g_monster_spider_target_recheck_delay;
  14. float autocvar_g_monster_spider_target_range;
  15. float autocvar_g_monster_spider_attack_type;
  16.  
  17. // spider animations
  18. #define spider_anim_idle 0
  19. #define spider_anim_walk 1
  20. #define spider_anim_attack 2
  21. #define spider_anim_attack2 3
  22. #define spider_anim_stone 4
  23.  
  24. const vector SPIDER_MIN = '-18 -18 -25';
  25. const vector SPIDER_MAX = '18 18 30';
  26.  
  27. .float spider_type; // used to switch between fire & ice attacks
  28. const float SPIDER_TYPE_ICE = 0;
  29. const float SPIDER_TYPE_FIRE = 1;
  30.  
  31. void spider_spawn();
  32. void spawnfunc_monster_spider();
  33. void spider_think();
  34.  
  35. void spider_die ()
  36. {
  37. if (!self.monster_noitemdrop) Monster_CheckDropCvars ("spider");
  38.  
  39. self.angles += '180 0 0';
  40. self.solid = SOLID_NOT;
  41. self.event_damage = monsters_gibdamage;
  42. self.enemy = world;
  43. self.movetype = MOVETYPE_TOSS;
  44. self.think = Monster_Fade;
  45. self.nextthink = time + (autocvar_g_monsters_fade_delay * 0.9);
  46. self.pain_finished = self.nextthink;
  47. self.frame = spider_anim_attack;
  48.  
  49. monster_hook_death(); // for post-death mods
  50. }
  51.  
  52. /**
  53. * Performe a standing attack on self.enemy.
  54. */
  55. void spider_attack_standing() {
  56. if (self.frozen)
  57. return;
  58.  
  59. if (self.stoned)
  60. return;
  61.  
  62. float dot = 0, bigdmg = autocvar_g_monster_spider_attack_stand_damage * self.scale;
  63.  
  64. self.velocity_x = 0;
  65. self.velocity_y = 0;
  66.  
  67. if(self.monster_owner == self.enemy)
  68. {
  69. self.enemy = world;
  70. return;
  71. }
  72.  
  73. makevectors (self.angles);
  74. dot = normalize (self.enemy.origin - self.origin) * v_forward;
  75. if(dot > 0.3)
  76. {
  77. Damage(self.enemy, self, self, bigdmg * monster_skill, DEATH_MONSTER_MELEE, self.origin, '0 0 0');
  78. }
  79.  
  80. if (!monster_isvalidtarget(self.enemy, self, FALSE, FALSE))
  81. self.enemy = world;
  82.  
  83. if(random() < 0.50)
  84. if (self.stoned || self.frozen) self.frame = spider_anim_stone; else self.frame = spider_anim_attack;
  85. else
  86. if (self.stoned || self.frozen) self.frame = spider_anim_stone; else self.frame = spider_anim_attack2;
  87.  
  88. self.nextthink = time + autocvar_g_monster_spider_attack_stand_delay;
  89. }
  90.  
  91. void spider_web_explode ()
  92. {
  93. RadiusDamage (self, self.realowner, 0, 0, 1, world, 0, self.projectiledeathtype, other);
  94. remove (self);
  95. }
  96.  
  97. void freezetag_Freeze(entity attacker);
  98. void spider_web_touch ()
  99. {
  100. PROJECTILE_TOUCH;
  101. if (other.takedamage == DAMAGE_AIM) {
  102. //print("freeze2\n");
  103. entity oldself;
  104. oldself = self;
  105. self = other;
  106. Freeze(other, 0.3, 1); //(Target, Time, Type(0 = ice, 1 = para)
  107. self = oldself;
  108. }
  109.  
  110. spider_web_explode();
  111. }
  112.  
  113. void spider_shootweb()
  114. {
  115. // clone of the electro secondary attack, with less bouncing
  116. entity proj = world;
  117.  
  118. makevectors(self.angles);
  119.  
  120. W_SetupShot_ProjectileSize (self, '0 0 -4', '0 0 -4', FALSE, 2, "machines/steam_burst.ogg", CH_WEAPON_A, 0);
  121.  
  122. w_shotdir = v_forward; // no TrueAim for grenades please
  123.  
  124. pointparticles(particleeffectnum("deluge_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
  125.  
  126. proj = spawn ();
  127. proj.classname = "plasma";
  128. proj.owner = proj.realowner = self;
  129. proj.use = spider_web_touch;
  130. proj.think = adaptor_think2use_hittype_splash;
  131. proj.bot_dodge = TRUE;
  132. proj.bot_dodgerating = 0;
  133. proj.nextthink = time + autocvar_g_balance_electro_secondary_lifetime;
  134. PROJECTILE_MAKETRIGGER(proj);
  135. proj.projectiledeathtype = DEATH_MONSTER_MELEE;
  136. setorigin(proj, w_shotorg);
  137.  
  138. //proj.glow_size = 50;
  139. //proj.glow_color = 45;
  140. proj.movetype = MOVETYPE_BOUNCE;
  141. W_SETUPPROJECTILEVELOCITY_UP(proj, g_balance_electro_secondary);
  142. proj.touch = spider_web_touch;
  143. setsize(proj, '0 0 -4', '0 0 -4');
  144. proj.takedamage = DAMAGE_YES;
  145. proj.damageforcescale = 0;
  146. proj.health = 500;
  147. proj.event_damage = W_Plasma_Damage;
  148. proj.flags = FL_PROJECTILE;
  149. proj.damagedbycontents = TRUE;
  150.  
  151. proj.bouncefactor = 0.3;
  152. proj.bouncestop = 0.05;
  153. proj.missile_flags = MIF_SPLASH | MIF_ARC;
  154.  
  155. CSQCProjectile(proj, TRUE, PROJECTILE_DELUGE, FALSE); // no culling, it has sound
  156.  
  157. other = proj; MUTATOR_CALLHOOK(EditProjectile);
  158. }
  159.  
  160. void spider_attack_leap()
  161. {
  162. if (self.frozen)
  163. return;
  164.  
  165. if (self.stoned)
  166. return;
  167.  
  168. vector angles_face = vectoangles(self.enemy.origin - self.origin);
  169.  
  170. // face the enemy
  171. if (self.stoned || self.frozen) self.frame = spider_anim_stone; else self.frame = spider_anim_attack2;
  172. self.angles_y = angles_face_y ;
  173. self.nextthink = time + autocvar_g_monster_spider_attack_leap_delay;
  174.  
  175. makevectors(self.angles);
  176.  
  177. switch(self.spider_type)
  178. {
  179. default:
  180. case SPIDER_TYPE_ICE:
  181. spider_shootweb(); break; // must... remember... breaks!
  182. case SPIDER_TYPE_FIRE:
  183. W_Fireball_Attack2(); break;
  184. }
  185. }
  186.  
  187. void spider_think()
  188. {
  189. monster_hook_think();
  190.  
  191. float finished = FALSE, enemyDistance = 0, mySpeed = 0;
  192.  
  193. if (self.stoned || self.frozen)
  194. self.frame = spider_anim_stone;
  195.  
  196. self.think = spider_think;
  197.  
  198. if(self.enemy && !monster_isvalidtarget(self.enemy, self, FALSE, FALSE))
  199. self.enemy = world;
  200.  
  201. if (self.enemy)
  202. if (self.enemy.team == self.team || self.monster_owner == self.enemy)
  203. self.enemy = world;
  204.  
  205. if(teamplay && autocvar_g_monsters_teams && self.monster_owner.team != self.team)
  206. self.monster_owner = world;
  207.  
  208. // remove enemy that ran away
  209. if (self.enemy)
  210. if (self.delay <= time) // check if we can do the rescan now
  211. if (vlen(self.origin - self.enemy.origin) > autocvar_g_monster_spider_target_range * self.scale)
  212. {
  213. //print("removing enemy, he is too far: ", ftos(vlen(self.origin - self.enemy.origin)), "\n");
  214. //print("delay was ", ftos(self.delay), "\n");
  215. self.enemy = world;
  216. }
  217. else
  218. self.delay = time + autocvar_g_monster_spider_target_recheck_delay;
  219.  
  220. // find an enemy if no enemy available
  221. if not(self.enemy)
  222. {
  223. self.enemy = FindTarget(self);
  224. if (self.enemy)
  225. self.delay = time + autocvar_g_monster_spider_target_recheck_delay;
  226. }
  227.  
  228. if (self.enemy)
  229. {
  230. // this spider has an enemy, attack if close enough, go to it if not!
  231. traceline(self.origin, self.enemy.origin, FALSE, self);
  232. enemyDistance = vlen(trace_endpos - self.origin);
  233. mySpeed = vlen(self.velocity);
  234.  
  235. //print("speed ", ftos(mySpeed), "\n");
  236.  
  237. if (trace_ent == self.enemy)
  238. if (self.enemy.deadflag == DEAD_NO)
  239. if (enemyDistance <= autocvar_g_monster_spider_attack_stand_range * self.scale && mySpeed <= 30)
  240. {
  241.  
  242. //RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity ignore, float forceintensity, float deathtype, entity directhitentity)
  243. spider_attack_standing();
  244. finished = TRUE;
  245. }
  246. else if (enemyDistance <= autocvar_g_monster_spider_attack_leap_range * self.scale && !self.enemy.frozen)
  247. {
  248. // do attackleap (set yaw, velocity, and check do damage on the first player entity it touches)
  249. spider_attack_leap();
  250. finished = TRUE;
  251. }
  252.  
  253. }
  254.  
  255. self.nextthink = time + 1 + self.monster_thinkadd + autocvar_g_monsters_thinkadd; //Randomness so they don't all think on the same frame causing hangs and clicks
  256.  
  257. if not(finished)
  258. {
  259. monster_move(autocvar_g_monster_spider_speed_run, autocvar_g_monster_spider_speed_walk, autocvar_g_monster_spider_stopspeed, spider_anim_walk, spider_anim_walk, spider_anim_idle);
  260.  
  261. if (self.enemy || self.monster_owner)
  262. {
  263. self.nextthink = time + 0.1;
  264. return;
  265. }
  266. }
  267.  
  268. if not(self.enemy || self.monster_owner || self.goalentity)
  269. {
  270. // stay idle
  271. //print("spider is idling while waiting for some fresh meat...\n");
  272. if (mySpeed <= 10)
  273. if (self.stoned || self.frozen) self.frame = spider_anim_stone; else self.frame = spider_anim_idle;
  274. else
  275. if (self.stoned || self.frozen) self.frame = spider_anim_stone; else self.frame = spider_anim_walk;
  276. self.nextthink = time + autocvar_g_monster_spider_idle_timer_min * random();
  277. }
  278. }
  279.  
  280. /**
  281. * Spawn the spider.
  282. */
  283. void spider_spawn()
  284. {
  285. if not(self.monster_forcetype) {
  286. //Mix
  287. if ((!self.scale) || (self.scale == 1))
  288. if not(self.scale == 1.5) {
  289. self.scale = 0.01 + (random() * 0.25);
  290. self.mins = SPIDER_MIN;
  291. self.maxs = SPIDER_MAX;
  292. self.mins_x *= self.scale;
  293. self.mins_y *= self.scale;
  294. self.mins_z *= self.scale;
  295. self.maxs_x *= self.scale;
  296. self.maxs_y *= self.scale;
  297. self.maxs_z *= self.scale;
  298. setsize(self, self.mins, self.maxs);
  299. }
  300.  
  301. if (self.scale > 0.5)
  302. self.skin = 1;
  303. } else {
  304. if (self.monster_forcetype == 1) {
  305. //Small
  306. if ((!self.scale) || (self.scale == 1) || (self.scale == 1.5))
  307. {
  308. //Bosses/Giants are 1.5 scale at this point in the code
  309. if (self.scale != 1.5) {
  310. self.scale = 0.01 + (random() * 0.25);
  311. } else {
  312. self.scale = 0.20 + (random() * 0.25);
  313. }
  314. self.mins = SPIDER_MIN;
  315. self.maxs = SPIDER_MAX;
  316. self.mins_x *= self.scale;
  317. self.mins_y *= self.scale;
  318. self.mins_z *= self.scale;
  319. self.maxs_x *= self.scale;
  320. self.maxs_y *= self.scale;
  321. self.maxs_z *= self.scale;
  322. setsize(self, self.mins, self.maxs);
  323. }
  324. self.skin = 0;
  325. } else if (self.monster_forcetype == 2) {
  326. //Huge
  327. if ((!self.scale) || (self.scale == 1) || (self.scale == 1.5))
  328. {
  329. if (self.scale != 1.5) {
  330. self.scale = 0.95 + (random() * 0.25);
  331. } else {
  332. self.scale = 1.05 + (random() * 2.50);
  333. }
  334. self.mins = SPIDER_MIN;
  335. self.maxs = SPIDER_MAX;
  336. self.mins_x *= self.scale;
  337. self.mins_y *= self.scale;
  338. self.mins_z *= self.scale;
  339. self.maxs_x *= self.scale;
  340. self.maxs_y *= self.scale;
  341. self.maxs_z *= self.scale;
  342. setsize(self, self.mins, self.maxs);
  343. }
  344. self.skin = 1;
  345. }
  346. }
  347.  
  348. if (self.monster_forcescale) {
  349. self.scale = self.monster_forcescale;
  350. self.mins = SPIDER_MIN;
  351. self.maxs = SPIDER_MAX;
  352. self.mins_x *= self.scale;
  353. self.mins_y *= self.scale;
  354. self.mins_z *= self.scale;
  355. self.maxs_x *= self.scale;
  356. self.maxs_y *= self.scale;
  357. self.maxs_z *= self.scale;
  358. setsize(self, self.mins, self.maxs);
  359. }
  360.  
  361. if (self.health <= 0)
  362. self.health = autocvar_g_monster_spider_health * self.scale;
  363.  
  364. self.ballistics_density = autocvar_g_ballistics_density_player;
  365. self.monster_thinkadd = ((random() - 0.5)*0.25);
  366.  
  367. self.stoneskin = 2;
  368. self.species = SPECIES_INSECT;
  369. self.classname = "monster_spider";
  370. self.nextthink = time + random() * 0.5 + 0.1;
  371. self.pain_finished = self.nextthink;
  372. self.frame = spider_anim_idle;
  373. self.think = spider_think;
  374. self.sprite_height = 40 * self.scale;
  375.  
  376. self.deadflag = DEAD_NO;
  377. monster_hook_spawn(); // for post-spawn mods
  378. }
  379.  
  380. /*QUAKED monster_spider (1 0 0) (-18 -18 -25) (18 18 47)
  381. Spider, 60 health points.
  382. -------- KEYS --------
  383. -------- SPAWNFLAGS --------
  384. MONSTERFLAG_APPEAR: monster will spawn when triggered.
  385. ---------NOTES----------
  386. -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
  387. modeldisabled="models/monsters/spider.dpm"
  388. */
  389. void spawnfunc_monster_spider()
  390. {
  391. if not(autocvar_g_monster_spider)
  392. {
  393. remove(self);
  394. return;
  395. }
  396.  
  397. self.monster_spawnfunc = spawnfunc_monster_spider;
  398. self.classname = "monster_spider";
  399. if(!self.spider_type)
  400. self.spider_type = autocvar_g_monster_spider_attack_type;
  401.  
  402. if(self.spawnflags & MONSTERFLAG_APPEAR)
  403. {
  404. self.think = func_null;
  405. self.nextthink = -1;
  406. self.use = Monster_Appear;
  407. return;
  408. }
  409.  
  410. if not (monster_initialize(
  411. "Spider",
  412. "models/monsters/spider.dpm",
  413. SPIDER_MIN, SPIDER_MAX,
  414. FALSE,
  415. spider_die, spider_spawn))
  416. {
  417. remove(self);
  418. return;
  419. }
  420. }
  421.  
  422. void spawnfunc_monster_spider_small()
  423. {
  424. if (self.scale)
  425. {
  426. self.monster_forcescale = self.scale;
  427. }
  428. self.monster_forcetype = 1;
  429. spawnfunc_monster_spider();
  430. }
  431.  
  432. void spawnfunc_monster_spider_huge()
  433. {
  434. if (self.scale)
  435. {
  436. self.monster_forcescale = self.scale;
  437. }
  438. self.monster_forcetype = 2;
  439. spawnfunc_monster_spider();
  440. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement