SHARE
TWEET

Untitled

a guest May 19th, 2019 112 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top