When the Solen Queen lays egg sac if not destroyed it spawns a helper. This all works well except the helper's life slowly drains til it dies as well as the queen after the egg hatches, what causes this and how can I control that effect or negate it?


This is the section with helper:
//Edit 2 of 2

public class BSQEggSac : Item, ICarvable

{

private SpawnTimer m_Timer;

public override string DefaultName

{

get { return "egg sac"; }

}

[Constructable]

public BSQEggSac()

: base(4316)

{

Movable = false;

Hue = 350;

m_Timer = new SpawnTimer(this);

m_Timer.Start();

}

public void Carve(Mobile from, Item item)

{

Effects.PlaySound(GetWorldLocation(), Map, 0x027);

Effects.SendLocationEffect(GetWorldLocation(), Map, 0x3728, 10, 10, 0, 0);

from.SendMessage("You destroy the egg sac.");

Delete();

m_Timer.Stop();

}

public BSQEggSac(Serial serial)

: base(serial)

{

}

public override void Serialize(GenericWriter writer)

{

base.Serialize(writer);

writer.Write((int)0); // version

}

public override void Deserialize(GenericReader reader)

{

base.Deserialize(reader);

int version = reader.ReadInt();

m_Timer = new SpawnTimer(this);

m_Timer.Start();

}

private class SpawnTimer : Timer

{

private Item m_Item;

public SpawnTimer(Item item)

: base(TimeSpan.FromSeconds(Utility.RandomMinMax(5, 10)))

{

Priority = TimerPriority.FiftyMS;

m_Item = item;

}

protected override void OnTick()

{

if (m_Item.Deleted)

return;

Mobile spawn;

switch (Utility.Random(2))

{

case 0:

spawn = new BlackSolenWarrior();

spawn.MoveToWorld(m_Item.Location, m_Item.Map);

m_Item.Delete();

break;

case 1:

spawn = new BlackSolenWorker();

spawn.MoveToWorld(m_Item.Location, m_Item.Map);

m_Item.Delete();

break;

}

}

}

} //End Edit

}

The entire file:
Code:
using System;

using System.Collections;

using Server.Items;

using Server.Network;

namespace Server.Mobiles

{

[CorpseName("a solen queen corpse")]

public class BlackSolenQueen : BaseCreature

{

private bool m_BurstSac;

[Constructable]

public BlackSolenQueen()

: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)

{

this.Name = "a black solen queen";

this.Body = 807;

this.BaseSoundID = 959;

this.Hue = 0x453;

this.SetStr(296, 320);

this.SetDex(121, 145);

this.SetInt(76, 100);

this.SetHits(151, 162);

this.SetDamage(10, 15);

this.SetDamageType(ResistanceType.Physical, 70);

this.SetDamageType(ResistanceType.Poison, 30);

this.SetResistance(ResistanceType.Physical, 30, 40);

this.SetResistance(ResistanceType.Fire, 30, 35);

this.SetResistance(ResistanceType.Cold, 25, 35);

this.SetResistance(ResistanceType.Poison, 35, 40);

this.SetResistance(ResistanceType.Energy, 25, 30);

this.SetSkill(SkillName.MagicResist, 70.0);

this.SetSkill(SkillName.Tactics, 90.0);

this.SetSkill(SkillName.Wrestling, 90.0);

this.Fame = 4500;

this.Karma = -4500;

this.VirtualArmor = 45;

SolenHelper.PackPicnicBasket(this);

this.PackItem(new ZoogiFungus((Utility.RandomDouble() > 0.05) ? 5 : 25));

if (Utility.RandomDouble() < 0.05)

this.PackItem(new BallOfSummoning());

}

public BlackSolenQueen(Serial serial)

: base(serial)

{

}

public bool BurstSac

{

get

{

return this.m_BurstSac;

}

}

public override int GetAngerSound()

{

return 0x259;

}

public override int GetIdleSound()

{

return 0x259;

}

public override int GetAttackSound()

{

return 0x195;

}

public override int GetHurtSound()

{

return 0x250;

}

public override int GetDeathSound()

{

return 0x25B;

}

public override void GenerateLoot()

{

this.AddLoot(LootPack.Rich);

}

//Edit 1 of 2

public override void OnGotMeleeAttack(Mobile attacker)

{

if (attacker.Weapon is BaseRanged)

BeginAcidBreath();

else if (this.Map != null && attacker != this && 0.25 > Utility.RandomDouble())

{

BSQEggSac sac = new BSQEggSac();

sac.MoveToWorld(this.Location, this.Map);

PlaySound(0x582);

Say(1114445); // * * The solen queen summons her workers to her aid! * *

}

base.OnGotMeleeAttack(attacker);

}

public override void OnDamagedBySpell(Mobile attacker)

{

base.OnDamagedBySpell(attacker);

BeginAcidBreath();

}

#region Acid Breath

private DateTime m_NextAcidBreath;

public void BeginAcidBreath()

{

PlayerMobile m = Combatant as PlayerMobile;

if (m == null || m.Deleted || !m.Alive || !Alive || m_NextAcidBreath > DateTime.Now || !CanBeHarmful(m))

return;

PlaySound(0x118);

MovingEffect(m, 0x36D4, 1, 0, false, false, 0x3F, 0);

TimeSpan delay = TimeSpan.FromSeconds(GetDistanceToSqrt(m) / 5.0);

Timer.DelayCall<Mobile>(delay, new TimerStateCallback<Mobile>(EndAcidBreath), m);

m_NextAcidBreath = DateTime.Now + TimeSpan.FromSeconds(5);

}

public void EndAcidBreath(Mobile m)

{

if (m == null || m.Deleted || !m.Alive || !Alive)

return;

if (0.2 >= Utility.RandomDouble())

m.ApplyPoison(this, Poison.Greater);

AOS.Damage(m, Utility.RandomMinMax(100, 120), 0, 0, 0, 100, 0);

}

#endregion

//End Edit

public override bool IsEnemy(Mobile m)

{

if (SolenHelper.CheckBlackFriendship(m))

return false;

else

return base.IsEnemy(m);

}

public override void OnDamage(int amount, Mobile from, bool willKill)

{

SolenHelper.OnBlackDamage(from);

if (!willKill)

{

if (!this.BurstSac)

{

if (this.Hits < 50)

{

this.PublicOverheadMessage(MessageType.Regular, 0x3B2, true, "* The solen's acid sac is burst open! *");

this.m_BurstSac = true;

}

}

else if (from != null && from != this && this.InRange(from, 1))

{

this.SpillAcid(from, 1);

}

}

base.OnDamage(amount, from, willKill);

}

public override bool OnBeforeDeath()

{

this.SpillAcid(4);

return base.OnBeforeDeath();

}

public override void Serialize(GenericWriter writer)

{

base.Serialize(writer);

writer.Write((int)1);

writer.Write(this.m_BurstSac);

}

public override void Deserialize(GenericReader reader)

{

base.Deserialize(reader);

int version = reader.ReadInt();



switch( version )

{

case 1:

{

this.m_BurstSac = reader.ReadBool();

break;

}

}

}

}

//Edit 2 of 2

public class BSQEggSac : Item, ICarvable

{

private SpawnTimer m_Timer;

public override string DefaultName

{

get { return "egg sac"; }

}

[Constructable]

public BSQEggSac()

: base(4316)

{

Movable = false;

Hue = 350;

m_Timer = new SpawnTimer(this);

m_Timer.Start();

}

public void Carve(Mobile from, Item item)

{

Effects.PlaySound(GetWorldLocation(), Map, 0x027);

Effects.SendLocationEffect(GetWorldLocation(), Map, 0x3728, 10, 10, 0, 0);

from.SendMessage("You destroy the egg sac.");

Delete();

m_Timer.Stop();

}

public BSQEggSac(Serial serial)

: base(serial)

{

}

public override void Serialize(GenericWriter writer)

{

base.Serialize(writer);

writer.Write((int)0); // version

}

public override void Deserialize(GenericReader reader)

{

base.Deserialize(reader);

int version = reader.ReadInt();

m_Timer = new SpawnTimer(this);

m_Timer.Start();

}

private class SpawnTimer : Timer

{

private Item m_Item;

public SpawnTimer(Item item)

: base(TimeSpan.FromSeconds(Utility.RandomMinMax(5, 10)))

{

Priority = TimerPriority.FiftyMS;

m_Item = item;

}

protected override void OnTick()

{

if (m_Item.Deleted)

return;

Mobile spawn;

switch (Utility.Random(2))

{

case 0:

spawn = new BlackSolenWarrior();

spawn.MoveToWorld(m_Item.Location, m_Item.Map);

m_Item.Delete();

break;

case 1:

spawn = new BlackSolenWorker();

spawn.MoveToWorld(m_Item.Location, m_Item.Map);

m_Item.Delete();

break;

}

}

}

} //End Edit

}
 
Last edited:
I think your issue is that you poison it? m.ApplyPoison(this, Poison.Greater);
that is poison spit has chance to poison the player. Im referring to the spawning egg sac mobile, as well as the queen both start to lose hitpoints once the egg appears/hatches
 
Tested the script and it works fine? I thought the ApplyPoison would be the other way around so that was my mistake ;)

But yea they spawn fine and do not get damage over time.

Also maybe a delay between each egg? :p spawned like 10 at once since high dex and a lot of hits
 
I just retested it and it seems to be fine now. Must been something else. Thanx for your input, Ill see about a delay timer that might be needed, back at it, let's see what I come up with next :)
 
Back