// Constructor public SkillInstance(Skill skill = null, Entity castedBy = null) { _caster = castedBy; _skill = skill; if(_skill != null) _skillStage = _skill.currentStage; }
// Constructor public SkillInstance(Skill skill = null, Entity castedBy = null) { _caster = castedBy; _skill = skill; if (_skill != null) { _skillStage = _skill.currentStage; } }
// Draw a skill stage void DrawSkillStage(Skill.Stage stage) { // Position /*switch(stage.posType) { * case Skill.PositionType.AtRightHand: * break; * * case Skill.PositionType.AboveCaster: * break; * * case Skill.PositionType.AtHitPoint: * break; * }*/ GUI.skin.textField.wordWrap = true; stage.description = EditorGUILayout.TextField(stage.description, GUILayout.Width(0), GUILayout.Height(descriptionHeight), GUILayout.ExpandWidth(true)); stage.castDuration = EditorGUILayout.FloatField(stage.castDuration, valueHeight); stage.cooldown = EditorGUILayout.FloatField(stage.cooldown, valueHeight); stage.effectId = (SkillEffectId)EditorGUILayout.EnumPopup(stage.effectId, valueHeight); stage.animType = (Skill.CastAnimation)EditorGUILayout.EnumPopup(stage.animType, valueHeight); stage.posType = (Skill.PositionType)EditorGUILayout.EnumPopup(stage.posType, valueHeight); using (new GUIHorizontal()) { //stage.posOffset.x = EditorGUILayout.FloatField(stage.posOffset.x, valueHeight); stage.posOffset.y = EditorGUILayout.FloatField(stage.posOffset.y, valueHeight); //stage.posOffset.z = EditorGUILayout.FloatField(stage.posOffset.z, valueHeight); } stage.rotType = (Skill.RotationType)EditorGUILayout.EnumPopup(stage.rotType, valueHeight); stage.castEffectPrefab = (GameObject)EditorGUILayout.ObjectField(stage.castEffectPrefab, typeof(GameObject), false, valueHeight); //stage.attackParticlesType = (Skill.ParticlesType)EditorGUILayout.EnumPopup(stage.attackParticlesType, valueHeight); using (new GUIHorizontal()) { for (int i = 0; i < stage.castVoices.Length; i++) { stage.castVoices[i] = (AudioClip)EditorGUILayout.ObjectField(stage.castVoices[i], typeof(AudioClip), false, valueHeight); } if (GUILayout.Button("+", GUILayout.Width(22))) { var nList = new List <AudioClip>(stage.castVoices); nList.Add(null); stage.castVoices = nList.ToArray(); } if (GUILayout.Button("-", GUILayout.Width(22))) { var nList = new List <AudioClip>(stage.castVoices); nList.RemoveAt(nList.Count - 1); stage.castVoices = nList.ToArray(); } } stage.energyCostAbs = EditorGUILayout.FloatField(stage.energyCostAbs, valueHeight); stage.lifeDrainRel = EditorGUILayout.FloatField(stage.lifeDrainRel, valueHeight); stage.powerMultiplier = EditorGUILayout.FloatField(stage.powerMultiplier, valueHeight); stage.staggerDuration = EditorGUILayout.FloatField(stage.staggerDuration, valueHeight); stage.canMoveWhileCasting = EditorGUILayout.Toggle(stage.canMoveWhileCasting, valueHeight); stage.canMoveWhileAttacking = EditorGUILayout.Toggle(stage.canMoveWhileAttacking, valueHeight); stage.isRuneDetonator = EditorGUILayout.Toggle(stage.isRuneDetonator, valueHeight); stage.runeType = (Skill.RuneType)EditorGUILayout.EnumPopup(stage.runeType, valueHeight); }
// Applies damage to the player public static void ApplyDamage(Entity entity, SkillInstance skillInstance, int power) { // Dead entity or protected by spawn protection if (!entity.isAlive || entity.hasSpawnProtection || !GameManager.gameStarted) { return; } // Caster of the skill Entity caster = skillInstance.caster; // Get stats of the caster and the player PlayerQueueStats casterStats = caster.stats.total; PlayerQueueStats playerStats = entity.stats.total; // Blocked hits if (entity.blocking) { // Show blocked text if (GameManager.isClient) { if (caster == Player.main) { Entity.SpawnText(entity, "Blocked", new Color(1.0f, 0.5f, 0.0f, 1.0f)); } else if (entity == Player.main) { Entity.SpawnText(entity, "Blocked", new Color(1.0f, 0.5f, 0.0f, 1.0f), -1f, 0, Config.instance.ownDmgOffset); } } // Player blocked a hit, count them playerStats.blocks += 1; casterStats.blocksTaken += 1; // Generate threat entity.AddThreat(caster, 0); // Player blocked: Outta here. return; } // Player didn't block. // The skill used Skill skill = skillInstance.skill; Skill.Stage skillStage = skillInstance.skillStage; // Wake up player if he was sleeping and the skill is a damage skill if (power > 0 && entity.slept > 0) { entity.EndSleep(); entity.slept = 0; } // Calculate the actual damage int dmg = entity.GetModifiedDamage(power * caster.charStats.attackDmgMultiplier * caster.currentWeapon.damageMultiplier); //LogManager.General.Log("Dmg: " + dmg + ", Power: " + power); // Detonate runes if (skillStage.isRuneDetonator) { entity.DetonateRunes(caster); } // Depending on whether this is the server or client we do different stuff if (GameManager.isServer) { // Apply stagger if (skillStage.staggerDuration > 0f) { entity.networkView.RPC("Stagger", uLink.RPCMode.All, skillStage.staggerDuration); } // CC effects if (skillStage.effect != null) { entity.networkView.RPC("ReceiveSkillEffect", uLink.RPCMode.All, (byte)skillStage.effect.id, caster.id); } // Apply runes if (skillStage.runeType != Skill.RuneType.None) { byte runeId = (byte)((int)(skillStage.runeType) - 1); entity.networkView.RPC("ReceiveRune", uLink.RPCMode.All, runeId); } // Skill damage log if (entity.skillDamageReceived.ContainsKey(skill.id)) { entity.skillDamageReceived[skill.id] += dmg; } else { entity.skillDamageReceived.Add(skill.id, dmg); } // How many hits did each player do (to save assists) if (entity.hitsByPlayer.ContainsKey(caster)) { entity.hitsByPlayer[caster] += 1; } else { entity.hitsByPlayer.Add(caster, 1); } // The actual application of damage entity.health -= dmg; // Caster scored a hit. // Update the total hit counter: casterStats.hits += 1; playerStats.hitsTaken += 1; // Life drain // TODO: Only drain the actual amount of HP / damage he did if (skillStage.lifeDrainRel > 0) { int lifeDrain = (int)(dmg * skillStage.lifeDrainRel); // Life drain needs to be capped at 100% if (lifeDrain > dmg) { lifeDrain = dmg; } casterStats.lifeDrain += lifeDrain; playerStats.lifeDrainTaken += lifeDrain; caster.health += lifeDrain; } // Generate threat entity.AddThreat(caster, dmg); } else if (power != 0) { // Client shows dmg number if (caster == Player.main) { Entity.SpawnText(entity, dmg.ToString(), new Color(1.0f, 1.0f, 0.4f, 1.0f)); } else if (entity == Player.main) { Entity.SpawnText(entity, dmg.ToString(), new Color(1.0f, 0.0f, 0.0f, 1.0f), -1f, 0, Config.instance.ownDmgOffset); } // Client shows life drain heal if (skillStage.lifeDrainRel > 0 && (caster == Player.main || entity == Player.main)) { if (caster == Player.main) { Entity.SpawnText(caster, "+" + ((int)(dmg * skillStage.lifeDrainRel)), new Color(0.0f, 1.0f, 0.0f, 1.0f), -1f, 0, Config.instance.ownDmgOffset); } else if (entity == Player.main) { Entity.SpawnText(caster, "+" + ((int)(dmg * skillStage.lifeDrainRel)), new Color(0.2f, 1.0f, 0.2f, 1.0f)); } } } // Update combo counter if (caster.comboCounter != null) { caster.comboCounter.AddHit(dmg); } // Last hit entity.lastHitBy = caster; entity.lastHitBySkill = skill; caster.entityLastHit = entity; // Update CC stats if (skillStage.effect != null) { casterStats.cc += 1; playerStats.ccTaken += 1; } // Update damage stats casterStats.damage += dmg; playerStats.damageTaken += dmg; }
// Spawn skill instance protected SkillInstance SpawnSkillInstance( UnityEngine.Object prefab, Skill skill, Skill.Stage skillStage, Vector3 skillPosition, Quaternion skillRotation, Vector3 hitPoint ) { GameObject clone = (GameObject)UnityEngine.Object.Instantiate(prefab, skillPosition, skillRotation); clone.transform.parent = skillInstancesRoot; // Disable some stuff on server if (GameManager.isServer) { // Audio on server if (clone.audio != null) { Destroy(clone.audio); } /*// Particles on server * if(clone.particleEmitter != null) * clone.particleEmitter.enabled = false; * * var pSystem = clone.particleSystem; * if(pSystem != null) { * pSystem.enableEmission = false; * if(!pSystem.isStopped) * pSystem.Stop(); * }*/ } // Set skill instance info lastSkillInstance = clone.GetComponent <SkillInstance>(); lastSkillInstance.caster = this; lastSkillInstance.skill = skill; lastSkillInstance.skillStage = skillStage; lastSkillInstance.hitPoint = hitPoint; // HINT: Change this to Entity.MoveToLayer() if you have collider children // We iterate the skill layers Entity.MoveToLayer(clone, Config.instance.skillLayersStart + SkillInstance.layerCounter); SkillInstance.layerCounter = (SkillInstance.layerCounter + 1) % Config.instance.skillLayersCount; // Ignore collision with the caster if (lastSkillInstance.collider != null) { if (party != null) { foreach (var member in party.members) { Physics.IgnoreCollision(lastSkillInstance.collider, member.collider); if (member.weaponModelCollider != null) { Physics.IgnoreCollision(lastSkillInstance.collider, member.weaponModelCollider); } } } else if (lastSkillInstance.collider) { Physics.IgnoreCollision(lastSkillInstance.collider, collider); if (weaponModelCollider != null) { Physics.IgnoreCollision(lastSkillInstance.collider, weaponModelCollider); } } } // Destroy after a few seconds if (!skill.canHold) { Destroy(clone, Config.instance.skillInstanceDestructionTime); } return(lastSkillInstance); }