public bool Run(params object[] args) { NWCreature oPC = NWCreature.Wrap(_.GetEnteringObject()); if (!oPC.IsPlayer) { return(false); } string triggerID = _.GetLocalString(Object.OBJECT_SELF, "TRIGGER_ID"); if (string.IsNullOrWhiteSpace(triggerID)) { triggerID = Guid.NewGuid().ToString(); _.SetLocalString(Object.OBJECT_SELF, "TRIGGER_ID", triggerID); } if (_.GetLocalInt(oPC.Object, triggerID) == 1) { return(false); } string message = _.GetLocalString(Object.OBJECT_SELF, "DISPLAY_TEXT"); _.SendMessageToPC(oPC.Object, _colorToken.Cyan(message)); _.SetLocalInt(oPC.Object, triggerID, 1); _.AssignCommand(oPC.Object, () => _.PlaySound("gui_prompt")); return(true); }
public void OnNPCPhysicallyAttacked() { NWCreature self = NWCreature.Wrap(Object.OBJECT_SELF); NWCreature attacker = NWCreature.Wrap(_.GetLastAttacker(Object.OBJECT_SELF)); AdjustEnmity(self, attacker, 0, 1); }
public void OnHitCastSpell(NWPlayer oPC) { NWObject oTarget = NWObject.Wrap(_.GetSpellTargetObject()); int activeWeaponSkillID = oPC.GetLocalInt("ACTIVE_WEAPON_SKILL"); if (activeWeaponSkillID <= 0) { return; } Data.Entities.Perk entity = _db.Perks.Single(x => x.PerkID == activeWeaponSkillID); IPerk perk = App.ResolveByInterface <IPerk>("Perk." + entity.JavaScriptName); if (perk.CanCastSpell(oPC, oTarget)) { perk.OnImpact(oPC, oTarget); if (oTarget.IsNPC) { ApplyEnmity(oPC, NWCreature.Wrap(oTarget.Object), entity); } } else { oPC.SendMessage(perk.CannotCastSpellMessage(oPC, oTarget) ?? "That ability cannot be used at this time."); } oPC.DeleteLocalString("ACTIVE_WEAPON_SKILL_UUID"); oPC.DeleteLocalInt("ACTIVE_WEAPON_SKILL"); }
public bool Run(params object[] args) { NWPlayer pc = NWPlayer.Wrap(_.GetLastUsedBy()); if (!pc.IsValid) { pc = NWPlayer.Wrap(_.GetPCSpeaker()); } string conversation = _.GetLocalString(Object.OBJECT_SELF, "CONVERSATION"); if (!string.IsNullOrWhiteSpace(conversation)) { int objectType = _.GetObjectType(Object.OBJECT_SELF); if (objectType == OBJECT_TYPE_PLACEABLE) { NWPlaceable talkTo = NWPlaceable.Wrap(Object.OBJECT_SELF); _dialog.StartConversation(pc, talkTo, conversation); } else { NWCreature talkTo = NWCreature.Wrap(Object.OBJECT_SELF); _dialog.StartConversation(pc, talkTo, conversation); } } else { _.ActionStartConversation(pc.Object, "", TRUE, FALSE); } return(true); }
public void OnImpact(NWPlayer oPC, NWObject oTarget) { int level = _perk.GetPCPerkLevel(oPC, PerkType.HolyShot); int damage; int alterationBonus = oPC.EffectiveAlterationBonus; switch (level) { case 1: damage = _random.Random(8 + alterationBonus) + 1; break; case 2: damage = _random.Random(6 + alterationBonus) + 1; damage += _random.Random(6 + alterationBonus) + 1; break; case 3: damage = _random.Random(6 + alterationBonus) + 1; damage += _random.Random(6 + alterationBonus) + 1; break; case 4: damage = _random.Random(4 + alterationBonus) + 1; damage += _random.Random(4 + alterationBonus) + 1; damage += _random.Random(4 + alterationBonus) + 1; damage += _random.Random(4 + alterationBonus) + 1; break; case 5: damage = _random.Random(4 + alterationBonus) + 1; damage += _random.Random(4 + alterationBonus) + 1; damage += _random.Random(4 + alterationBonus) + 1; damage += _random.Random(4 + alterationBonus) + 1; damage += _random.Random(4 + alterationBonus) + 1; break; default: return; } int wisdom = oPC.WisdomModifier; int intelligence = oPC.IntelligenceModifier; float damageMultiplier = 1.0f + (intelligence * 0.4f) + (wisdom * 0.2f); damage = (int)(damage * damageMultiplier); Effect vfx = _.EffectBeam(VFX_BEAM_SILENT_HOLY, oPC.Object, BODY_NODE_CHEST); _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, vfx, oTarget.Object, 1.5f); _skill.RegisterPCToNPCForSkill(oPC, NWCreature.Wrap(oTarget.Object), SkillType.AlterationMagic); oPC.AssignCommand(() => { _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectDamage(damage), oTarget.Object); }); }
public OnCreatureEvent(ISkillService skill, ILootService loot, IBehaviourService behaviour) { Self = NWCreature.Wrap(Object.OBJECT_SELF); _skill = skill; _loot = loot; _behaviour = behaviour; }
public void OnNPCDamaged() { NWCreature self = NWCreature.Wrap(Object.OBJECT_SELF); NWCreature damager = NWCreature.Wrap(_.GetLastDamager(Object.OBJECT_SELF)); int enmityAmount = _.GetTotalDamageDealt(); if (enmityAmount <= 0) { enmityAmount = 1; } AdjustEnmity(self, damager, 0, enmityAmount); }
public void OnPlayerDamaged() { NWPlayer player = NWPlayer.Wrap(Object.OBJECT_SELF); NWCreature npc = NWCreature.Wrap(_.GetLastDamager(Object.OBJECT_SELF)); if (!player.IsPlayer || !npc.IsNPC) { return; } int damage = _.GetTotalDamageDealt(); Enmity enmity = GetEnmity(npc, player); enmity.CumulativeAmount -= damage; }
public NWCreature DeserializeCreature(string base64String, Location location) { if (location == null) { throw new ArgumentException("Invalid target location during creature deserialization."); } NWCreature creature = NWCreature.Wrap(_nwnxObject.Deserialize(base64String)); if (creature.Object == null) { throw new NullReferenceException("Unable to deserialize creature."); } creature.Location = location; return(creature); }
public void RegisterPCToAllCombatTargetsForSkill(NWPlayer player, SkillType skillType) { int skillID = (int)skillType; if (!player.IsPlayer) { return; } if (skillID <= 0) { return; } List <NWPlayer> members = new List <NWPlayer>(); NWPlayer member = NWPlayer.Wrap(_.GetFirstFactionMember(player.Object)); while (member.IsValid) { members.Add(member); member = NWPlayer.Wrap(_.GetNextFactionMember(player.Object)); } int nth = 1; NWCreature creature = NWCreature.Wrap(_.GetNearestCreature(CREATURE_TYPE_IS_ALIVE, 1, player.Object, nth, CREATURE_TYPE_PLAYER_CHAR, 0)); while (creature.IsValid) { if (_.GetDistanceBetween(player.Object, creature.Object) > 20.0f) { break; } NWObject target = NWObject.Wrap(_.GetAttackTarget(creature.Object)); if (target.IsValid && members.Contains(target)) { if (target.IsValid && target.Area.Equals(player.Area)) { RegisterPCToNPCForSkill(player, creature, skillID); } } nth++; creature = NWCreature.Wrap(_.GetNearestCreature(CREATURE_TYPE_IS_ALIVE, 1, player.Object, nth, CREATURE_TYPE_PLAYER_CHAR, 0)); } }
public void OnHitCastSpell(NWPlayer oPC) { if (!oPC.IsPlayer) { return; } NWItem oSpellOrigin = NWItem.Wrap(_.GetSpellCastItem()); NWCreature oTarget = NWCreature.Wrap(_.GetSpellTargetObject()); int skillID = GetWeaponSkillID(oSpellOrigin); if (skillID <= -1) { return; } if (oTarget.IsPlayer || oTarget.IsDM) { return; } if (oTarget.ObjectType != OBJECT_TYPE_CREATURE) { return; } CreatureSkillRegistration reg = GetCreatureSkillRegistration(oTarget.GlobalID); reg.AddSkillRegistrationPoint(oPC, skillID, oSpellOrigin.RecommendedLevel); // Add a registration point if a shield is equipped. This is to prevent players from swapping out a weapon for a shield // just before they kill an enemy. NWItem oShield = oPC.LeftHand; if (oShield.BaseItemType == BASE_ITEM_SMALLSHIELD || oShield.BaseItemType == BASE_ITEM_LARGESHIELD || oShield.BaseItemType == BASE_ITEM_TOWERSHIELD) { reg.AddSkillRegistrationPoint(oPC, (int)SkillType.Shields, oShield.RecommendedLevel); } if (_random.Random(100) + 1 <= 3) { _food.DecreaseHungerLevel(oPC, 1); } }
private void HandleApplySneakAttackDamage(DamageData data) { NWObject damager = data.Damager; int sneakAttackType = damager.GetLocalInt("SNEAK_ATTACK_ACTIVE"); if (damager.IsPlayer && sneakAttackType > 0) { NWPlayer player = NWPlayer.Wrap(damager.Object); NWCreature target = NWCreature.Wrap(Object.OBJECT_SELF); int perkRank = _perk.GetPCPerkByID(damager.GlobalID, (int)PerkType.SneakAttack).PerkLevel; int perkBonus = 1; // Rank 4 increases damage bonus by 2x (total: 3x) if (perkRank == 4) { perkBonus = 2; } float perkRate; if (sneakAttackType == 1) // Player is behind target. { perkRate = 1.0f * perkBonus; } else // Player is anywhere else. { perkRate = 0.5f * perkBonus; } float damageRate = 1.0f + perkRate + (player.EffectiveSneakAttackBonus * 0.05f); data.Base = (int)(data.Base * damageRate); if (target.IsNPC) { _enmity.AdjustEnmity(target, player, 5 * data.Base); } _nwnxDamage.SetDamageEventData(data); } damager.DeleteLocalInt("SNEAK_ATTACK_ACTIVE"); }
private void DoPeekOutside() { const float MaxDistance = 2.5f; NWPlaceable door = (NWPlaceable)GetDialogTarget(); Location location = door.GetLocalLocation("PLAYER_HOME_EXIT_LOCATION"); int numberFound = 0; int nth = 1; NWCreature nearest = NWCreature.Wrap(_.GetNearestObjectToLocation(OBJECT_TYPE_CREATURE, location, nth)); while (nearest.IsValid) { if (_.GetDistanceBetweenLocations(location, nearest.Location) > MaxDistance) { break; } if (nearest.IsPlayer) { numberFound++; } nth++; nearest = NWCreature.Wrap(_.GetNearestObjectToLocation(OBJECT_TYPE_CREATURE, location, nth)); } if (numberFound <= 0) { _.FloatingTextStringOnCreature("You don't see anyone outside.", GetPC().Object, FALSE); } else if (numberFound == 1) { _.FloatingTextStringOnCreature("You see one person outside.", GetPC().Object, FALSE); } else { _.FloatingTextStringOnCreature("You see " + numberFound + " people outside.", GetPC().Object, FALSE); } }
public void RegisterPCToAllCombatTargetsForSkill(NWPlayer pc, int skillID) { if (!pc.IsPlayer || skillID <= 0) { return; } List <NWCreature> members = new List <NWCreature>(); NWN.Object member = _.GetFirstFactionMember(pc.Object); while (_.GetIsObjectValid(member) == TRUE) { members.Add(NWCreature.Wrap(member)); member = _.GetNextFactionMember(pc.Object); } int nth = 1; NWCreature creature = NWCreature.Wrap(_.GetNearestCreature(CREATURE_TYPE_IS_ALIVE, 1, pc.Object, nth, CREATURE_TYPE_PLAYER_CHAR, 0)); while (creature.IsValid) { if (_.GetDistanceBetween(pc.Object, creature.Object) > 20.0f) { break; } NWCreature target = NWCreature.Wrap(_.GetAttackTarget(creature.Object)); if (target.IsValid && members.Contains(target)) { if (target.IsValid && target.Area.Equals(pc.Area)) { RegisterPCToNPCForSkill(pc, creature, skillID); } } nth++; creature = NWCreature.Wrap(_.GetNearestCreature(CREATURE_TYPE_IS_ALIVE, 1, pc.Object, nth, CREATURE_TYPE_PLAYER_CHAR, 0)); } }
public BehaviourTreeBuilder Build(BehaviourTreeBuilder builder, params object[] args) { return(builder.Do("AggroTargetBySound", t => { NWCreature self = (NWCreature)args[0]; if (self.IsInCombat) { return BehaviourTreeStatus.Failure; } float aggroRange = self.GetLocalFloat("AGGRO_RANGE"); if (aggroRange <= 0.0f) { aggroRange = 5.0f; } int nth = 1; NWCreature creature = NWCreature.Wrap(_.GetNearestObject(NWScript.OBJECT_TYPE_CREATURE, self.Object, nth)); while (creature.IsValid) { if (_.GetIsEnemy(creature.Object, self.Object) == NWScript.TRUE && !_enmity.IsOnEnmityTable(self, creature) && !creature.HasAnyEffect(NWScript.EFFECT_TYPE_SANCTUARY) && _.GetDistanceBetween(self.Object, creature.Object) <= aggroRange && _.LineOfSightObject(self.Object, creature.Object) == NWScript.TRUE) { _enmity.AdjustEnmity(self, creature, 0, 1); } nth++; creature = NWCreature.Wrap(_.GetNearestObject(NWScript.OBJECT_TYPE_CREATURE, self.Object, nth)); } return BehaviourTreeStatus.Running; })); }
public BehaviourTreeBuilder Build(BehaviourTreeBuilder builder, params object[] args) { return(builder.Do("AggroTargetBySight", t => { NWCreature self = (NWCreature)args[0]; if (self.IsInCombat) { return BehaviourTreeStatus.Failure; } float aggroRange = self.GetLocalFloat("AGGRO_RANGE"); if (aggroRange <= 0.0f) { aggroRange = 10.0f; } Location targetLocation = _.Location( self.Area.Object, _biowarePos.GetChangedPosition(self.Position, aggroRange, self.Facing), self.Facing + 180.0f); NWCreature creature = NWCreature.Wrap(_.GetFirstObjectInShape(NWScript.SHAPE_SPELLCYLINDER, aggroRange, targetLocation, NWScript.TRUE, NWScript.OBJECT_TYPE_CREATURE, self.Position)); while (creature.IsValid) { if (_.GetIsEnemy(creature.Object, self.Object) == NWScript.TRUE && !_enmity.IsOnEnmityTable(self, creature) && _.GetDistanceBetween(self.Object, creature.Object) <= aggroRange && !creature.HasAnyEffect(NWScript.EFFECT_TYPE_INVISIBILITY, NWScript.EFFECT_TYPE_SANCTUARY)) { _enmity.AdjustEnmity(self, creature, 0, 1); } creature = NWCreature.Wrap(_.GetNextObjectInShape(NWScript.SHAPE_SPELLCYLINDER, aggroRange, targetLocation, NWScript.TRUE, NWScript.OBJECT_TYPE_CREATURE, self.Position)); } return BehaviourTreeStatus.Running; })); }
public void OnImpact(NWPlayer oPC, NWObject oTarget) { NWCreature npc = NWCreature.Wrap(oTarget.Object); Effect vfx = _.EffectVisualEffect(VFX_IMP_CHARM); _.ApplyEffectToObject(DURATION_TYPE_INSTANT, vfx, oTarget.Object); oPC.AssignCommand(() => { _.ActionPlayAnimation(ANIMATION_FIREFORGET_TAUNT, 1f, 1f); }); _enmity.AdjustEnmity(npc, oPC, 120); // todo debugging EnmityTable table = _enmity.GetEnmityTable(npc); foreach (var x in table.Values) { Console.WriteLine(npc.Name + ", " + x.TargetObject.Name + ": Volatile = " + x.VolatileAmount + ", Cumulative: " + x.CumulativeAmount); } // todo end debugging }
protected CreatureBase() { Self = NWCreature.Wrap(Object.OBJECT_SELF); }
public void OnModuleUseFeat() { NWPlayer pc = NWPlayer.Wrap(Object.OBJECT_SELF); NWCreature target = NWCreature.Wrap(_nwnxEvents.OnFeatUsed_GetTarget().Object); int featID = _nwnxEvents.OnFeatUsed_GetFeatID(); Data.Entities.Perk perk = _db.Perks.SingleOrDefault(x => x.FeatID == featID); if (perk == null) { return; } IPerk perkAction = App.ResolveByInterface <IPerk>("Perk." + perk.JavaScriptName); if (perkAction == null) { return; } PlayerCharacter playerEntity = _db.PlayerCharacters.Single(x => x.PlayerID == pc.GlobalID); if (_perk.GetPCPerkLevel(pc, perk.PerkID) <= 0) { pc.SendMessage("You do not meet the prerequisites to use this ability."); return; } if (perkAction.IsHostile() && target.IsPlayer) { if (!_pvpSanctuary.IsPVPAttackAllowed(pc, NWPlayer.Wrap(target.Object))) { return; } } if (pc.Area.Resref != target.Area.Resref || _.LineOfSightObject(pc.Object, target.Object) == 0) { pc.SendMessage("You cannot see your target."); return; } if (!perkAction.CanCastSpell(pc, target)) { pc.SendMessage(perkAction.CannotCastSpellMessage(pc, target) ?? "That ability cannot be used at this time."); return; } int manaCost = perkAction.ManaCost(pc, perkAction.ManaCost(pc, perk.BaseManaCost)); if (playerEntity.CurrentMana < manaCost) { pc.SendMessage("You do not have enough mana. (Required: " + manaCost + ". You have: " + playerEntity.CurrentMana + ")"); return; } if (pc.IsBusy || pc.CurrentHP <= 0) { pc.SendMessage("You are too busy to activate that ability."); return; } // Check cooldown PCCooldown pcCooldown = _db.PCCooldowns.SingleOrDefault(x => x.PlayerID == pc.GlobalID && x.CooldownCategoryID == perk.CooldownCategoryID); if (pcCooldown == null) { pcCooldown = new PCCooldown { CooldownCategoryID = Convert.ToInt32(perk.CooldownCategoryID), DateUnlocked = DateTime.UtcNow.AddSeconds(-1), PlayerID = pc.GlobalID }; _db.PCCooldowns.Add(pcCooldown); _db.SaveChanges(); } DateTime unlockDateTime = pcCooldown.DateUnlocked; DateTime now = DateTime.UtcNow; if (unlockDateTime > now) { string timeToWait = _time.GetTimeToWaitLongIntervals(now, unlockDateTime, false); pc.SendMessage("That ability can be used again in " + timeToWait + "."); return; } // Spells w/ casting time if (perk.PerkExecutionType.PerkExecutionTypeID == (int)PerkExecutionType.Spell) { CastSpell(pc, target, perk, perkAction, perk.CooldownCategory); } // Combat Abilities w/o casting time else if (perk.PerkExecutionType.PerkExecutionTypeID == (int)PerkExecutionType.CombatAbility) { perkAction.OnImpact(pc, target); ApplyEnmity(pc, target, perk); if (manaCost > 0) { playerEntity.CurrentMana = playerEntity.CurrentMana - manaCost; _db.SaveChanges(); } ApplyCooldown(pc, perk.CooldownCategory, perkAction); } // Queued Weapon Skills else if (perk.PerkExecutionType.PerkExecutionTypeID == (int)PerkExecutionType.QueuedWeaponSkill) { HandleQueueWeaponSkill(pc, perk, perkAction); } }
private void CastSpell(NWPlayer pc, NWObject target, Data.Entities.Perk entity, IPerk perk, CooldownCategory cooldown) { string spellUUID = Guid.NewGuid().ToString("N"); int itemBonus = pc.EffectiveCastingSpeed; float baseCastingTime = perk.CastingTime(pc, (float)entity.BaseCastingTime); float castingTime = baseCastingTime; // Casting Bonus % - Shorten casting time. if (itemBonus < 0) { float castingPercentageBonus = Math.Abs(itemBonus) * 0.01f; castingTime = castingTime - (castingTime * castingPercentageBonus); } // Casting Penalty % - Increase casting time. else if (itemBonus > 0) { float castingPercentageBonus = Math.Abs(itemBonus) * 0.01f; castingTime = castingTime + (castingTime * castingPercentageBonus); } if (castingTime < 0.5f) { castingTime = 0.5f; } // Heavy armor increases casting time by 2x the base casting time if (pc.Chest.CustomItemType == CustomItemType.HeavyArmor) { castingTime = baseCastingTime * 2; } if (_.GetActionMode(pc.Object, ACTION_MODE_STEALTH) == 1) { _.SetActionMode(pc.Object, ACTION_MODE_STEALTH, 0); } _.ClearAllActions(); _biowarePosition.TurnToFaceObject(target, pc); _.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, _.EffectVisualEffect(VFX_DUR_ELEMENTAL_SHIELD), pc.Object, castingTime + 0.2f); float animationTime = castingTime; pc.AssignCommand(() => _.ActionPlayAnimation(ANIMATION_LOOPING_CONJURE1, 1.0f, animationTime - 0.1f)); pc.IsBusy = true; CheckForSpellInterruption(pc, spellUUID, pc.Position); pc.SetLocalInt(spellUUID, SPELL_STATUS_STARTED); _nwnxPlayer.StartGuiTimingBar(pc, (int)castingTime, ""); pc.DelayCommand(() => { if (pc.GetLocalInt(spellUUID) == SPELL_STATUS_INTERRUPTED || // Moved during casting pc.CurrentHP < 0 || pc.IsDead) // Or is dead/dying { pc.DeleteLocalInt(spellUUID); pc.SendMessage("Your spell has been interrupted."); return; } pc.DeleteLocalInt(spellUUID); if ((PerkExecutionType)entity.ExecutionTypeID == PerkExecutionType.Spell || (PerkExecutionType)entity.ExecutionTypeID == PerkExecutionType.CombatAbility) { perk.OnImpact(pc, target); if (target.IsNPC) { ApplyEnmity(pc, NWCreature.Wrap(target.Object), entity); } } else { HandleQueueWeaponSkill(pc, entity, perk); } // Adjust mana only if spell cost > 0 PlayerCharacter pcEntity = _db.PlayerCharacters.Single(x => x.PlayerID == pc.GlobalID); if (perk.ManaCost(pc, entity.BaseManaCost) > 0) { pcEntity.CurrentMana = pcEntity.CurrentMana - perk.ManaCost(pc, entity.BaseManaCost); _db.SaveChanges(); pc.SendMessage(_color.Custom("Mana: " + pcEntity.CurrentMana + " / " + pcEntity.MaxMana, 32, 223, 219)); } if (_random.Random(100) + 1 <= 3) { _food.DecreaseHungerLevel(pc, 1); } if (!_customEffect.DoesPCHaveCustomEffect(pc, CustomEffectType.Chainspell)) { // Mark cooldown on category ApplyCooldown(pc, cooldown, perk); } pc.IsBusy = false; }, castingTime + 0.5f); }
protected BehaviourBase() { Self = NWCreature.Wrap(Object.OBJECT_SELF); }