public static void Enter(CLRScriptBase s, ALFA.Shared.ActiveTrap trap) { uint enterer = s.GetEnteringObject(); if (trap.IsFiring) { // Trap's already firing. It'll reset when it runs out of targets. return; } // If one is enough, we don't need to check the trigger's contents. if (trap.MinimumToTrigger == 1) { if (FitsTrapTargetRestriction(s, trap, enterer)) { Fire(s, trap); } } else { int validTargets = 0; foreach (uint contents in s.GetObjectsInPersistentObject(s.GetObjectByTag(trap.Tag, 0), OBJECT_TYPE_CREATURE, 0)) { if (FitsTrapTargetRestriction(s, trap, contents)) { validTargets++; } } if (validTargets >= trap.MinimumToTrigger) { Fire(s, trap); } } }
private static bool IsInArea(CLRScriptBase s, ALFA.Shared.ActiveTrap trap, uint creature) { uint nwTrap = s.GetObjectByTag(trap.DetectTag, 0); foreach (uint item in s.GetObjectsInPersistentObject(nwTrap, OBJECT_TYPE_CREATURE, PERSISTENT_ZONE_ACTIVE)) { if (item == creature) { return true; } } return false; }
public static void Fire(CLRScriptBase s, ALFA.Shared.ActiveTrap trap, uint specialTarget) { List<uint> targets = new List<uint>(); if (s.GetIsObjectValid(specialTarget) == TRUE) { targets.Add(specialTarget); } foreach (uint contents in s.GetObjectsInPersistentObject(s.GetObjectByTag(trap.Tag, 0), OBJECT_TYPE_CREATURE, 0)) { if (FitsTrapTargetRestriction(s, trap, contents)) { targets.Add(contents); } } if (targets.Count == 0) { // Might be that they all left. In any case // we have nothing to shoot trap.IsFiring = false; return; } uint target; if (targets.Count == 1) { target = targets[0]; } else { target = targets[s.Random(targets.Count)]; } uint caster; if (s.GetIsObjectValid(trap.TrapOrigin) == FALSE) { caster = s.GetObjectByTag(trap.Tag, 0); } else { caster = trap.TrapOrigin; } if (trap.SpellTrap) { // It's a spell-- guess this is simple. s.AssignCommand(caster, delegate { s.ActionCastSpellAtObject(trap.SpellId, target, METAMAGIC_NONE, TRUE, 0, 0, 1); }); } else { foreach (uint victim in s.GetObjectsInShape(trap.EffectArea, trap.EffectSize, s.GetLocation(target), false, OBJECT_TYPE_CREATURE, s.GetPosition(caster))) { s.ApplyEffectToObject(DURATION_TYPE_INSTANT, GetTrapEffect(s, trap, victim), victim, 0.0f); _doSoloVFX(s, trap, victim); } _doGroupVFX(s, trap, s.GetLocation(target)); } if (trap.NumberOfShots > -1) { if (trap.NumberOfShots < 2) { TrapDisable.RemoveTrap(s, trap); return; } else { trap.NumberOfShots--; } } trap.IsFiring = true; s.DelayCommand(6.0f, delegate { Fire(s, trap); }); }
private static void SwimHeartbeat(CLRScriptBase script, uint Creature) { uint Trigger = AppearanceTypes.currentSwimTrigger[Creature]; foreach(uint contents in script.GetObjectsInPersistentObject(Trigger, CLRScriptBase.OBJECT_TYPE_CREATURE, CLRScriptBase.PERSISTENT_ZONE_ACTIVE)) { if(contents == Creature) { if (script.GetSubRace(Creature) != CLRScriptBase.RACIAL_SUBTYPE_WATER_GENASI && script.GetLocalInt(Creature, ACR_CREATURE_AQUATIC) == 0) { int SwimDC = script.GetLocalInt(Trigger, ACR_SWIM_DC); int SinkDC = SwimDC - 5; int NoAir = script.GetLocalInt(Trigger, ACR_NO_AIR); int Roll = script.d20(1); int Bonus = script.GetSkillRank(CLRScriptBase.SKILL_SWIM, Creature, CLRScriptBase.FALSE); ProcessWaterEffects(script, Creature, Trigger); if (10 + Bonus >= SwimDC) { // Can take 10 here. Roll = 10; } if (Roll + Bonus >= SwimDC) { script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_TEMPORARY, script.ExtraordinaryEffect(script.EffectMovementSpeedDecrease(50)), Creature, 6.0f); script.SendMessageToPC(Creature, String.Format("*Swim: {0} + {1} = {2} v. DC {3} :: Success!*", Roll, Bonus, Roll+Bonus, SwimDC)); if(NoAir == CLRScriptBase.FALSE) { CurrentDrownStatus.Remove(Creature); CurrentDrownDC.Remove(Creature); } else { ProcessNoAir(script, Creature); } } else if (Roll + Bonus >= SinkDC) { script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_TEMPORARY, script.ExtraordinaryEffect(script.EffectMovementSpeedDecrease(75)), Creature, 6.0f); script.SendMessageToPC(Creature, String.Format("*Swim: {0} + {1} = {2} v. DC {3} :: Failure!*", Roll, Bonus, Roll + Bonus, SwimDC)); script.SendMessageToPC(Creature, String.Format("You struggle to move through the water.")); if (NoAir == CLRScriptBase.FALSE) { CurrentDrownStatus.Remove(Creature); CurrentDrownDC.Remove(Creature); } else { ProcessNoAir(script, Creature); } } else { script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_TEMPORARY, script.ExtraordinaryEffect(script.EffectMovementSpeedDecrease(75)), Creature, 6.0f); // TODO: Find a way to apply this penalty without completely screwing the PC's AC. //script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_TEMPORARY, script.ExtraordinaryEffect(script.EffectACDecrease(2, CLRScriptBase.AC_DODGE_BONUS, CLRScriptBase.DAMAGE_TYPE_ALL)), Creature, 6.0f); script.SendMessageToPC(Creature, String.Format("*Swim: {0} + {1} = {2} v. DC {3} :: Failure!*", Roll, Bonus, Roll + Bonus, SwimDC)); script.SendMessageToPC(Creature, String.Format("You're completely overwhelmed by the pull of the water!")); ProcessNoAir(script, Creature); } } else { script.SendMessageToPC(Creature, "Your swim speed and capacity to breathe water allows you to move easily through the water."); return; } script.DelayCommand(6.0f, delegate { SwimHeartbeat(script, Creature); }); return; } } AppearanceTypes.currentSwimTrigger[Creature] = CLRScriptBase.OBJECT_INVALID; AppearanceTypes.characterMovement[Creature] = AppearanceTypes.MovementType.Walking; if (Swimming.CurrentDrownStatus.ContainsKey(Creature)) Swimming.CurrentDrownStatus.Remove(Creature); AppearanceTypes.RecalculateMovement(script, Creature); }