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 void HandleTrapDetected(CLRScriptBase s, ALFA.Shared.ActiveTrap trap, uint detector) { trap.Detected = true; NWEffect vfx = s.SupernaturalEffect(s.EffectNWN2SpecialEffectFile(trap.TrapTriggerVFX, OBJECT_INVALID, s.Vector(0.0f, 0.0f, 0.0f))); s.ApplyEffectToObject(DURATION_TYPE_PERMANENT, vfx, s.GetObjectByTag(trap.Tag, 0), 0.0f); uint detectWidget = s.CreateObject(OBJECT_TYPE_PLACEABLE, "acr_trap_disarm", s.GetLocation(detector), TRUE, trap.Tag + "_"); if (!String.IsNullOrEmpty(trap.Description)) { s.SetDescription(detectWidget, trap.Description); } s.SetFirstName(detectWidget, String.Format("Disarm the {0} trap", trap.SpellTrap ? "Spell" : "Mechanical")); // If they clicked to walk, let's stop them from walking into the hazard they just found. if (s.GetCurrentAction(detector) == ACTION_MOVETOPOINT) { s.AssignCommand(detector, delegate { s.ClearAllActions(0); }); } s.PlaySound("alert", FALSE); s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.SupernaturalEffect(s.EffectNWN2SpecialEffectFile("fx_bang", detector, s.Vector(0.0f,0.0f,0.0f))), detector, 6.0f); s.SendMessageToPC(detector, "You spot a 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; }
private void PopulateArea(CLRScriptBase script) { List<Vector3> trapsToSpawn = new List<Vector3>(); if (!DungeonStore.DungeonSpawns.ContainsKey(SpawnType)) return; foreach(uint wp in script.GetObjectsInArea(AreaId)) { if(script.GetTag(wp) == "MONSTER_LOW") { if (DungeonStore.DungeonSpawns[SpawnType].ContainsKey(CR / 3)) { script.CreateObject(CLRScriptBase.OBJECT_TYPE_CREATURE, DungeonStore.DungeonSpawns[SpawnType][CR/3][rand.Next(DungeonStore.DungeonSpawns[SpawnType][CR/3].Count)], script.GetLocation(wp), CLRScriptBase.TRUE, ""); } } else if(script.GetTag(wp) == "MONSTER_MED") { if (DungeonStore.DungeonSpawns[SpawnType].ContainsKey(CR / 2)) { script.CreateObject(CLRScriptBase.OBJECT_TYPE_CREATURE, DungeonStore.DungeonSpawns[SpawnType][CR/2][rand.Next(DungeonStore.DungeonSpawns[SpawnType][CR/2].Count)], script.GetLocation(wp), CLRScriptBase.TRUE, ""); } } else if(script.GetTag(wp) == "MONSTER_HIGH") { if (DungeonStore.DungeonSpawns[SpawnType].ContainsKey(CR)) { script.CreateObject(CLRScriptBase.OBJECT_TYPE_CREATURE, DungeonStore.DungeonSpawns[SpawnType][CR][rand.Next(DungeonStore.DungeonSpawns[SpawnType][CR].Count)], script.GetLocation(wp), CLRScriptBase.TRUE, ""); } if (!questSpawned) { questSpawned = true; NWEffect AoE = script.EffectAreaOfEffect(86, "acf_trg_onenter", "acf_trg_onheartbeat", "acf_trg_onexit", "AOE"+Quest); script.ApplyEffectAtLocation(CLRScriptBase.DURATION_TYPE_PERMANENT, script.SupernaturalEffect(AoE), script.GetLocation(wp), 0.0f); uint spawnedAoE = script.GetObjectByTag("AOE" + Quest, 0); script.SetLocalString(spawnedAoE, "ACR_QST_NAME", Quest); script.SetLocalInt(spawnedAoE, "ACR_QST_LOWER_STATE", 1); script.SetLocalInt(spawnedAoE, "ACR_QST_UPPER_STATE", 2); script.SetLocalString(spawnedAoE, "ACR_QST_MESSAGE", "This appears to be the end of the dungeon, and your path here is scouted."); } } else if (script.GetTag(wp) == "TRAP") { if(DungeonStore.DungeonTraps[TrapType].ContainsKey(CR)) { trapsToSpawn.Add(script.GetPosition(wp)); } } } foreach (Vector3 trap in trapsToSpawn) { script.ClearScriptParams(); script.AddScriptParameterInt(1); script.AddScriptParameterFloat(trap.x); script.AddScriptParameterFloat(trap.y); script.AddScriptParameterFloat(trap.z); script.AddScriptParameterObject(AreaId); script.AddScriptParameterInt(-1); script.AddScriptParameterInt(-1); script.AddScriptParameterFloat(-1.0f); script.AddScriptParameterInt(-1); script.AddScriptParameterInt(-1); script.AddScriptParameterInt(-1); script.AddScriptParameterInt(-1); script.AddScriptParameterInt(-1); script.AddScriptParameterInt(-1); script.AddScriptParameterObject(CLRScriptBase.OBJECT_INVALID); script.AddScriptParameterInt(-1); script.AddScriptParameterInt(-1); script.AddScriptParameterInt(-1); script.AddScriptParameterInt(-1); script.AddScriptParameterInt(-1); script.AddScriptParameterString(DungeonStore.DungeonTraps[TrapType][CR][rand.Next(DungeonStore.DungeonTraps[TrapType][CR].Count)]); script.ExecuteScriptEnhanced("ACR_Traps", script.GetModule(), CLRScriptBase.FALSE); } }
public static void RemoveTrap(CLRScriptBase s, ALFA.Shared.ActiveTrap trap) { uint triggerAOE = s.GetObjectByTag(trap.Tag, 0); uint detectAOE = s.GetObjectByTag(trap.DetectTag, 0); uint disarmPlaceable = s.GetObjectByTag(trap.Tag + "_", 0); s.DestroyObject(triggerAOE, 0.0f, FALSE); s.DestroyObject(detectAOE, 0.0f, FALSE); s.DestroyObject(disarmPlaceable, 0.0f, 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 NWEffect GetTrapEffect(CLRScriptBase s, ALFA.Shared.ActiveTrap trap, uint target) { int damage = 0; for (int count = 0; count < trap.DiceNumber; count++) { damage += s.Random(trap.DiceType) + 1; } if (trap.SaveDC > -1) { if (s.ReflexSave(target, trap.SaveDC, SAVING_THROW_TYPE_TRAP, s.GetObjectByTag(trap.Tag, 0)) != TRUE) { if (s.GetHasFeat(FEAT_IMPROVED_EVASION, target, TRUE) == TRUE) damage /= 2; } else { if (s.GetHasFeat(FEAT_EVASION, target, TRUE) == TRUE) damage = 0; else damage /= 2; } } else { int roll = new Random().Next(20) + 1; int final = roll + trap.AttackBonus; string hitormiss = " *hit* "; if (final < s.GetAC(target, FALSE) && roll != 20) { hitormiss = " *miss* "; damage = 0; } s.SendMessageToPC(target, "<C=DarkViolet>Trap</C><C=DarkOrange> attacks " + s.GetName(target) + ":" + hitormiss + ": " + roll + " + " + trap.AttackBonus + " = " + final); } NWEffect eVis = s.EffectVisualEffect(VFX_COM_HIT_DIVINE, FALSE); List<int> damageTypes = new List<int>(); if ((trap.DamageType & DAMAGE_TYPE_ACID) == DAMAGE_TYPE_ACID) { damageTypes.Add(DAMAGE_TYPE_ACID); eVis = s.EffectVisualEffect(VFX_COM_HIT_ACID, FALSE); } if ((trap.DamageType & DAMAGE_TYPE_BLUDGEONING) == DAMAGE_TYPE_BLUDGEONING) { damageTypes.Add(DAMAGE_TYPE_BLUDGEONING); eVis = s.EffectVisualEffect(VFX_COM_BLOOD_CRT_RED, FALSE); } if ((trap.DamageType & DAMAGE_TYPE_COLD) == DAMAGE_TYPE_COLD) { damageTypes.Add(DAMAGE_TYPE_COLD); eVis = s.EffectVisualEffect(VFX_COM_HIT_FROST, FALSE); } if ((trap.DamageType & DAMAGE_TYPE_DIVINE) == DAMAGE_TYPE_DIVINE) { damageTypes.Add(DAMAGE_TYPE_DIVINE); eVis = s.EffectVisualEffect(VFX_COM_HIT_DIVINE, FALSE); } if ((trap.DamageType & DAMAGE_TYPE_ELECTRICAL) == DAMAGE_TYPE_ELECTRICAL) { damageTypes.Add(DAMAGE_TYPE_ELECTRICAL); eVis = s.EffectVisualEffect(VFX_COM_HIT_ELECTRICAL, FALSE); } if ((trap.DamageType & DAMAGE_TYPE_FIRE) == DAMAGE_TYPE_FIRE) { damageTypes.Add(DAMAGE_TYPE_FIRE); eVis = s.EffectVisualEffect(VFX_COM_HIT_FIRE, FALSE); } if ((trap.DamageType & DAMAGE_TYPE_MAGICAL) == DAMAGE_TYPE_MAGICAL) { damageTypes.Add(DAMAGE_TYPE_MAGICAL); eVis = s.EffectVisualEffect(VFX_COM_HIT_DIVINE, FALSE); } if ((trap.DamageType & DAMAGE_TYPE_NEGATIVE) == DAMAGE_TYPE_NEGATIVE) { damageTypes.Add(DAMAGE_TYPE_NEGATIVE); eVis = s.EffectVisualEffect(VFX_COM_HIT_NEGATIVE, FALSE); } if ((trap.DamageType & DAMAGE_TYPE_PIERCING) == DAMAGE_TYPE_PIERCING) { damageTypes.Add(DAMAGE_TYPE_PIERCING); eVis = s.EffectVisualEffect(VFX_COM_BLOOD_CRT_RED, FALSE); } if ((trap.DamageType & DAMAGE_TYPE_POSITIVE) == DAMAGE_TYPE_POSITIVE) { damageTypes.Add(DAMAGE_TYPE_POSITIVE); eVis = s.EffectVisualEffect(VFX_COM_HIT_DIVINE, FALSE); } if ((trap.DamageType & DAMAGE_TYPE_SLASHING) == DAMAGE_TYPE_SLASHING) { damageTypes.Add(DAMAGE_TYPE_SLASHING); eVis = s.EffectVisualEffect(VFX_COM_BLOOD_CRT_RED, FALSE); } if ((trap.DamageType & DAMAGE_TYPE_SONIC) == DAMAGE_TYPE_SONIC) { damageTypes.Add(DAMAGE_TYPE_SONIC); eVis = s.EffectVisualEffect(VFX_COM_HIT_SONIC, FALSE); } if (damage == 0) { return eVis; } NWEffect eDam = eVis; damage /= damageTypes.Count; if (damage < 1) damage = 1; foreach (int dmgType in damageTypes) { eDam = s.EffectLinkEffects(eDam, s.EffectDamage(damage, dmgType, DAMAGE_POWER_NORMAL, FALSE)); } return eDam; }
private static void _doSoloVFX(CLRScriptBase s, ALFA.Shared.ActiveTrap trap, uint target) { if (trap.EffectSize < 2.0f) { if (s.GetArea(trap.TrapOrigin) == s.GetArea(s.GetObjectByTag(trap.Tag, 0))) { if ((trap.DamageType & DAMAGE_TYPE_ACID) == DAMAGE_TYPE_ACID) { s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_ACID, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f); } if ((trap.DamageType & DAMAGE_TYPE_BLUDGEONING) == DAMAGE_TYPE_BLUDGEONING) { s.SpawnItemProjectile(trap.TrapOrigin, target, s.GetLocation(trap.TrapOrigin), s.GetLocation(target), BASE_ITEM_SLING, PROJECTILE_PATH_TYPE_HOMING, OVERRIDE_ATTACK_RESULT_HIT_SUCCESSFUL, 0); float fShotDelay = 0.1f; int c = 1; while (c < trap.DiceNumber) { s.DelayCommand(fShotDelay, delegate { s.SpawnItemProjectile(trap.TrapOrigin, target, s.GetLocation(trap.TrapOrigin), s.GetLocation(target), BASE_ITEM_SLING, PROJECTILE_PATH_TYPE_HOMING, OVERRIDE_ATTACK_RESULT_HIT_SUCCESSFUL, 0); }); fShotDelay += 0.1f; c++; } } if ((trap.DamageType & DAMAGE_TYPE_COLD) == DAMAGE_TYPE_COLD) { s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_ICE, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f); } if ((trap.DamageType & DAMAGE_TYPE_DIVINE) == DAMAGE_TYPE_DIVINE) { s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_HOLY, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f); } if ((trap.DamageType & DAMAGE_TYPE_ELECTRICAL) == DAMAGE_TYPE_ELECTRICAL) { s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_LIGHTNING, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f); } if ((trap.DamageType & DAMAGE_TYPE_FIRE) == DAMAGE_TYPE_FIRE) { s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_FIRE, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f); } if ((trap.DamageType & DAMAGE_TYPE_MAGICAL) == DAMAGE_TYPE_MAGICAL) { s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_MAGIC, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f); } if ((trap.DamageType & DAMAGE_TYPE_NEGATIVE) == DAMAGE_TYPE_NEGATIVE) { s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_EVIL, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f); } if ((trap.DamageType & DAMAGE_TYPE_PIERCING) == DAMAGE_TYPE_PIERCING) { s.SpawnItemProjectile(trap.TrapOrigin, target, s.GetLocation(trap.TrapOrigin), s.GetLocation(target), BASE_ITEM_DART, PROJECTILE_PATH_TYPE_HOMING, OVERRIDE_ATTACK_RESULT_HIT_SUCCESSFUL, 0); float fShotDelay = 0.1f; int c = 1; while (c < trap.DiceNumber) { s.SpawnItemProjectile(trap.TrapOrigin, target, s.GetLocation(trap.TrapOrigin), s.GetLocation(target), BASE_ITEM_DART, PROJECTILE_PATH_TYPE_HOMING, OVERRIDE_ATTACK_RESULT_HIT_SUCCESSFUL, 0); fShotDelay += 0.1f; c++; } } if ((trap.DamageType & DAMAGE_TYPE_POSITIVE) == DAMAGE_TYPE_POSITIVE) { s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_HOLY, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f); } if ((trap.DamageType & DAMAGE_TYPE_SLASHING) == DAMAGE_TYPE_SLASHING) { s.SpawnItemProjectile(trap.TrapOrigin, target, s.GetLocation(trap.TrapOrigin), s.GetLocation(target), BASE_ITEM_THROWINGAXE, PROJECTILE_PATH_TYPE_HOMING, OVERRIDE_ATTACK_RESULT_HIT_SUCCESSFUL, 0); float fShotDelay = 0.1f; int c = 1; while (c < trap.DiceNumber) { s.SpawnItemProjectile(trap.TrapOrigin, target, s.GetLocation(trap.TrapOrigin), s.GetLocation(target), BASE_ITEM_THROWINGAXE, PROJECTILE_PATH_TYPE_HOMING, OVERRIDE_ATTACK_RESULT_HIT_SUCCESSFUL, 0); fShotDelay += 0.1f; c++; } } if ((trap.DamageType & DAMAGE_TYPE_SONIC) == DAMAGE_TYPE_SONIC) { s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_SONIC, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f); } } else { // These are pretty much single-target effects. if ((trap.DamageType & DAMAGE_TYPE_ACID) == DAMAGE_TYPE_ACID) { s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_ACID_S, FALSE), target, 0.0f); } if ((trap.DamageType & DAMAGE_TYPE_BLUDGEONING) == DAMAGE_TYPE_BLUDGEONING) { s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_COM_BLOOD_CRT_RED, FALSE), target, 0.0f); } if ((trap.DamageType & DAMAGE_TYPE_COLD) == DAMAGE_TYPE_COLD) { s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_FROST_L, FALSE), target, 0.0f); } if ((trap.DamageType & DAMAGE_TYPE_DIVINE) == DAMAGE_TYPE_DIVINE) { s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_COM_HIT_DIVINE, FALSE), target, 0.0f); } if ((trap.DamageType & DAMAGE_TYPE_ELECTRICAL) == DAMAGE_TYPE_ELECTRICAL) { s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_LIGHTNING_S, FALSE), target, 0.0f); } if ((trap.DamageType & DAMAGE_TYPE_FIRE) == DAMAGE_TYPE_FIRE) { s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_FLAME_S, FALSE), target, 0.0f); } if ((trap.DamageType & DAMAGE_TYPE_MAGICAL) == DAMAGE_TYPE_MAGICAL) { s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_MAGBLUE, FALSE), target, 0.0f); } if ((trap.DamageType & DAMAGE_TYPE_NEGATIVE) == DAMAGE_TYPE_NEGATIVE) { s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_NEGATIVE_ENERGY, FALSE), target, 0.0f); } if ((trap.DamageType & DAMAGE_TYPE_PIERCING) == DAMAGE_TYPE_PIERCING) { s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_SPIKE_TRAP, FALSE), target, 0.0f); } if ((trap.DamageType & DAMAGE_TYPE_POSITIVE) == DAMAGE_TYPE_POSITIVE) { s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_SUNSTRIKE, FALSE), target, 0.0f); } if ((trap.DamageType & DAMAGE_TYPE_SLASHING) == DAMAGE_TYPE_SLASHING) { s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_COM_BLOOD_CRT_RED, FALSE), target, 0.0f); } if ((trap.DamageType & DAMAGE_TYPE_SONIC) == DAMAGE_TYPE_SONIC) { s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_SONIC, FALSE), target, 0.0f); } } } else { return; } }