]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Apply a few tweaks to make the spawner a bit more functional
authorMario <mario@smbclan.net>
Thu, 9 Mar 2017 23:11:42 +0000 (09:11 +1000)
committerMario <mario@smbclan.net>
Thu, 9 Mar 2017 23:11:42 +0000 (09:11 +1000)
qcsrc/common/monsters/monster/monster.qc
qcsrc/common/monsters/spawner.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/monsters/sv_monsters.qh
qcsrc/server/client.qc

index 5fcfbd516ff0062c385bbd2b6e8df8dba070b5fd..c26ecfe71ac7037e57672956f291999a0000083e 100644 (file)
@@ -13,6 +13,9 @@ const int MON_ATTACK_MELEE = BIT(0);
 const int MON_ATTACK_TOUCH = BIT(1);
 const int MON_ATTACK_PROJECTILE = BIT(2);
 
+const int MON_DAMAGE_NONE = BIT(0);
+const int MON_DAMAGE_NOMONSTERS = BIT(1);
+
 const int MON_ATTACKTYPE_GRENADE = 0;
 const int MON_ATTACKTYPE_FIREBALL = 1;
 
@@ -20,21 +23,30 @@ const int MON_ATTACKTYPE_FIREBALL = 1;
 
 // here come the fields
 .bool mon_jumpoff;
+.int mon_alwaysturn;
 .float mon_touchdelay, mon_touchangle;
 .float touch_timer; // reused field
 .float mon_jumpdelay, mon_jumpheight;
 .float jump_delay;
 .float shot_dmg, shot_radius;
 .float mon_proj_speed, mon_proj_speed_up;
+.float mon_attack_delay;
 
-.int mon_movetype, mon_attacks, mon_attacktype;
+.int mon_movetype, mon_attacks, mon_attacktype, mon_damageflags;
 
 void M_CustomMonster_Touch(entity this, entity toucher)
 {
-       if((this.mon_movetype & MON_MOVE_TOUCH) && time < this.touch_timer && vdist(this.velocity, <, this.speed))
+       if((this.mon_movetype & MON_MOVE_TOUCH) && vdist(this.velocity, <, this.speed))
        {
-               fixedmakevectors(toucher.angles);
-               this.velocity = v_forward * this.speed2;
+               if(time < this.touch_timer)
+                       return; // just return
+               if(IS_PLAYER(toucher))
+               {
+                       fixedmakevectors(toucher.angles);
+                       this.angles = toucher.angles; // to make sidescrolling movement work
+                       this.velocity = v_forward * this.speed2;
+                       this.attack_finished_single[0] = time + this.mon_attack_delay; // don't immediately damage the player that pushed it
+               }
                this.touch_timer = time + this.mon_touchdelay;
                return;
        }
@@ -58,7 +70,7 @@ void M_CustomMonster_Touch(entity this, entity toucher)
        if(vdir.z <= this.mon_touchangle)
        {
                Damage(toucher, this, this, this.dmg, DEATH_MONSTER_ZOMBIE_MELEE.m_id, toucher.origin, '0 0 0');
-               this.attack_finished_single[0] = time + this.delay;
+               this.attack_finished_single[0] = time + this.mon_attack_delay;
        }
 }
 
@@ -95,7 +107,7 @@ bool M_CustomMonster_Attack(int attack_type, entity actor, entity targ, .entity
                case MONSTER_ATTACK_MELEE:
                {
                        if(actor.mon_attacks & MON_ATTACK_MELEE)
-                               return Monster_Attack_Melee(actor, actor.enemy, actor.dmg, actor.anim_melee, actor.attack_range, actor.delay, DEATH_MONSTER_ZOMBIE_MELEE.m_id, actor.wait); // just fall back to zombie melee deathtype
+                               return Monster_Attack_Melee(actor, actor.enemy, actor.dmg, actor.anim_melee, actor.attack_range, actor.mon_attack_delay, DEATH_MONSTER_ZOMBIE_MELEE.m_id, actor.wait); // just fall back to zombie melee deathtype
                        return false;
                }
                case MONSTER_ATTACK_RANGED:
@@ -122,7 +134,7 @@ bool M_CustomMonster_Attack(int attack_type, entity actor, entity targ, .entity
                                makevectors(actor.angles);
                                W_SetupProjVelocity_Explicit(proj, v_forward, v_up, actor.mon_proj_speed, actor.mon_proj_speed_up, 0, 0, false);
                                UpdateCSQCProjectile(proj);
-                               actor.attack_finished_single[0] = time + (actor.delay * random());
+                               actor.attack_finished_single[0] = time + (actor.mon_attack_delay * random());
                                return true;
                        }
                        return false;
@@ -147,7 +159,9 @@ METHOD(CustomMonster, mr_think, bool(CustomMonster this, entity actor))
     }
     if(actor.mon_movetype & MON_MOVE_2D)
     {
-       Monster_Move_2D(actor, actor.speed, actor.mon_jumpoff);
+       if((actor.mon_movetype & MON_MOVE_TOUCH) && !vec2(actor.velocity))
+               return false; // wait until pushed
+       Monster_Move_2D(actor, actor.speed, actor.mon_jumpoff, actor.mon_alwaysturn);
        M_CustomMonster_TargetEnemey(actor); // not called by regular code in this case
        return false;
     }
@@ -161,8 +175,14 @@ METHOD(CustomMonster, mr_think, bool(CustomMonster this, entity actor))
 METHOD(CustomMonster, mr_pain, float(CustomMonster this, entity actor, float damage_take, entity attacker, float deathtype))
 {
     TC(CustomMonster, this);
+    if((actor.mon_damageflags & MON_DAMAGE_NONE))
+       return 0;
+    if((actor.mon_damageflags & MON_DAMAGE_NOMONSTERS) && IS_MONSTER(attacker))
+       return 0;
+
     setanim(actor, actor.anim_pain1, true, true, false);
     actor.pain_finished = actor.animstate_endtime;
+    actor.velocity = '0 0 0'; // reset velocity
     return damage_take;
 }
 
index a479c8a2e3afec219d6320d2997b5d48742f0566..af4ce841d4ae2543dd7da1449b8e27562f48edc5 100644 (file)
@@ -2,6 +2,8 @@
 
 bool autocvar_g_monster_spawner_copyfields = false; // just incase this gets too nasty
 
+.bool use_trigger_origin;
+
 void spawner_use(entity this, entity actor, entity trigger)
 {
        int moncount = 0;
@@ -29,7 +31,13 @@ void spawner_use(entity this, entity actor, entity trigger)
                e.monster_skill = this.monster_skill;
        }
 
-       e = spawnmonster(e, this.spawnmob, 0, this, this, this.origin, false, true, this.monster_moveflags);
+       vector org = this.origin;
+       if(this.use_trigger_origin)
+       {
+               org = trigger.origin; // TODO: doesn't support brushes
+               e.angles = trigger.angles;
+       }
+       e = spawnmonster(e, this.spawnmob, 0, this, this, org, false, true, this.monster_moveflags);
 }
 
 spawnfunc(monster_spawner)
index 80170e4725dae43c4ed4f50dc41f2c4c5baeceaa..aabec01d739c95af9a1ddacf86331ec62f55f84f 100644 (file)
@@ -1088,7 +1088,8 @@ void Monster_Damage(entity this, entity inflictor, entity attacker, float damage
        if(deathtype != DEATH_DROWN.m_id && deathtype != DEATH_FIRE.m_id && sound_allowed(MSG_BROADCAST, attacker))
                spamsound (this, CH_PAIN, SND(BODYIMPACT1), VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
 
-       this.velocity += force * this.damageforcescale;
+       if(this.damageforcescale > 0)
+               this.velocity += force * this.damageforcescale;
 
        if(deathtype != DEATH_DROWN.m_id && take)
        {
@@ -1125,7 +1126,7 @@ void Monster_Damage(entity this, entity inflictor, entity attacker, float damage
 }
 
 // don't check for enemies, just keep walking in a straight line
-void Monster_Move_2D(entity this, float mspeed, bool allow_jumpoff)
+void Monster_Move_2D(entity this, float mspeed, bool allow_jumpoff, int always_turn)
 {
        if(game_stopped || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || this.draggedby != NULL || time < game_starttime || (autocvar_g_campaign && !campaign_bots_may_start) || time < this.spawn_time)
        {
@@ -1145,9 +1146,9 @@ void Monster_Move_2D(entity this, float mspeed, bool allow_jumpoff)
        bool reverse = false;
        if(trace_fraction != 1.0)
                reverse = true;
-       if(trace_ent && IS_PLAYER(trace_ent) && !(trace_ent.items & ITEM_Strength.m_itemid))
+       if(!(always_turn & 1) && trace_ent && IS_PLAYER(trace_ent) && !(trace_ent.items & ITEM_Strength.m_itemid))
                reverse = false;
-       if(trace_ent && IS_MONSTER(trace_ent))
+       if(!(always_turn & 2) && trace_ent && IS_MONSTER(trace_ent))
                reverse = true;
 
        // TODO: fix this... tracing is broken if the floor is thin
index d0a5266d04f76b8a145de52f41e4604e62d30f22..ebd41f924fb0378b8a6534a9980d87b5ea1bd282 100644 (file)
@@ -80,7 +80,7 @@ void monster_setupcolors(entity this);
 
 void Monster_Touch(entity this, entity toucher);
 
-void Monster_Move_2D(entity this, float mspeed, float allow_jumpoff);
+void Monster_Move_2D(entity this, float mspeed, float allow_jumpoff, int always_turn);
 
 void Monster_Delay(entity this, int repeat_count, float defer_amnt, void(entity) func);
 
index ddbf0fd1c76d089a6b881c10011d344de7b3c3bc..2774e955f18bcf4307b2ae8417f9ae548ef1537b 100644 (file)
@@ -826,7 +826,7 @@ void DecodeLevelParms(entity this)
 {
        // load parms
        this.parm_idlesince = parm1;
-       if (this.parm_idlesince == -(86400 * 366))
+       if (this.parm_idlesince == -(86400 * 366)) // WTF
                this.parm_idlesince = time;
 
        // whatever happens, allow 60 seconds of idling directly after connect for map loading