From: Mario Date: Thu, 9 Mar 2017 23:11:42 +0000 (+1000) Subject: Apply a few tweaks to make the spawner a bit more functional X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=3e073d8f488612c291bdca2e5566e2907968eddb;p=xonotic%2Fxonotic-data.pk3dir.git Apply a few tweaks to make the spawner a bit more functional --- diff --git a/qcsrc/common/monsters/monster/monster.qc b/qcsrc/common/monsters/monster/monster.qc index 5fcfbd516..c26ecfe71 100644 --- a/qcsrc/common/monsters/monster/monster.qc +++ b/qcsrc/common/monsters/monster/monster.qc @@ -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; } diff --git a/qcsrc/common/monsters/spawner.qc b/qcsrc/common/monsters/spawner.qc index a479c8a2e..af4ce841d 100644 --- a/qcsrc/common/monsters/spawner.qc +++ b/qcsrc/common/monsters/spawner.qc @@ -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) diff --git a/qcsrc/common/monsters/sv_monsters.qc b/qcsrc/common/monsters/sv_monsters.qc index 80170e472..aabec01d7 100644 --- a/qcsrc/common/monsters/sv_monsters.qc +++ b/qcsrc/common/monsters/sv_monsters.qc @@ -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 diff --git a/qcsrc/common/monsters/sv_monsters.qh b/qcsrc/common/monsters/sv_monsters.qh index d0a5266d0..ebd41f924 100644 --- a/qcsrc/common/monsters/sv_monsters.qh +++ b/qcsrc/common/monsters/sv_monsters.qh @@ -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); diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index ddbf0fd1c..2774e955f 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -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