Add the triple shot spell.
加入三重射击法术。
This commit is contained in:
parent
407798b13b
commit
3f96519ac0
|
@ -7,4 +7,8 @@
|
||||||
- id: necromancy
|
- id: necromancy
|
||||||
scene_path: res://prefab/magics/curseOfTheUndead.tscn
|
scene_path: res://prefab/magics/curseOfTheUndead.tscn
|
||||||
icon_path: res://sprites/projectile/curseOfTheUndead.png
|
icon_path: res://sprites/projectile/curseOfTheUndead.png
|
||||||
|
max_stack_value: 1
|
||||||
|
- id: x3
|
||||||
|
scene_path: res://prefab/magics/x3.tscn
|
||||||
|
icon_path: res://sprites/projectile/x3.png
|
||||||
max_stack_value: 1
|
max_stack_value: 1
|
|
@ -4,4 +4,6 @@ item_staff_necromancy_desc,发射诅咒,可将敌人转化为邪恶的怪物
|
||||||
item_portable_backpacks,便携式背包,PortableBackpacks,ポータブルバックパック
|
item_portable_backpacks,便携式背包,PortableBackpacks,ポータブルバックパック
|
||||||
item_portable_backpacks_desc,为玩家提供9个物品槽。,Provides 9 item slots for the player.,プレイヤーに9つのアイテムスロットを提供します。
|
item_portable_backpacks_desc,为玩家提供9个物品槽。,Provides 9 item slots for the player.,プレイヤーに9つのアイテムスロットを提供します。
|
||||||
item_necromancy,死灵法术,necromancy,ネクロマンシー
|
item_necromancy,死灵法术,necromancy,ネクロマンシー
|
||||||
item_necromancy_desc,法术的实体化弹丸。,The materialized projectile of a spell.,術の実体化した弾丸です。
|
item_necromancy_desc,法术的实体化弹丸。,The materialized projectile of a spell.,術の実体化した弾丸です。
|
||||||
|
item_x3,三重射击法术,Triple shot spell,三重射撃術です
|
||||||
|
item_x3_desc,使发射器一次射出三颗弹丸。,Make the launcher shoot three pellets at a time.,発射機から一度に三つの弾丸を発射させます。
|
|
46
prefab/magics/x3.tscn
Normal file
46
prefab/magics/x3.tscn
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
[gd_scene load_steps=6 format=3 uid="uid://cg75t3fw5c6er"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scripts/spell/MultipleFireSpell.cs" id="1_cnhod"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://mb5yijtw7sw5" path="res://sprites/projectile/x3.png" id="3_b3s8h"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://cak6chjjsu7wo" path="res://sounds/fire.wav" id="4_ffr2k"]
|
||||||
|
|
||||||
|
[sub_resource type="RectangleShape2D" id="RectangleShape2D_3eq4k"]
|
||||||
|
size = Vector2(30, 30)
|
||||||
|
|
||||||
|
[sub_resource type="RectangleShape2D" id="RectangleShape2D_i3lbq"]
|
||||||
|
size = Vector2(30, 31)
|
||||||
|
|
||||||
|
[node name="x3" type="RigidBody2D"]
|
||||||
|
collision_layer = 8
|
||||||
|
collision_mask = 34
|
||||||
|
angular_damp = -1.0
|
||||||
|
script = ExtResource("1_cnhod")
|
||||||
|
|
||||||
|
[node name="DamageArea2D" type="Area2D" parent="."]
|
||||||
|
collision_layer = 8
|
||||||
|
collision_mask = 102
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="DamageArea2D"]
|
||||||
|
shape = SubResource("RectangleShape2D_3eq4k")
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||||
|
position = Vector2(0, -0.5)
|
||||||
|
shape = SubResource("RectangleShape2D_i3lbq")
|
||||||
|
|
||||||
|
[node name="Marker2D" type="Marker2D" parent="."]
|
||||||
|
position = Vector2(65, 0)
|
||||||
|
|
||||||
|
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="Marker2D"]
|
||||||
|
stream = ExtResource("4_ffr2k")
|
||||||
|
bus = &"SoundEffect"
|
||||||
|
|
||||||
|
[node name="TipLabel" type="Label" parent="."]
|
||||||
|
offset_left = -19.0
|
||||||
|
offset_top = 23.0
|
||||||
|
offset_right = 21.0
|
||||||
|
offset_bottom = 48.0
|
||||||
|
|
||||||
|
[node name="CurseOfTheUndead" type="Sprite2D" parent="."]
|
||||||
|
|
||||||
|
[node name="X3" type="Sprite2D" parent="."]
|
||||||
|
texture = ExtResource("3_b3s8h")
|
|
@ -45,6 +45,16 @@ position = Vector2(142, 84)
|
||||||
script = ExtResource("3_v1tlc")
|
script = ExtResource("3_v1tlc")
|
||||||
ItemId = "staff_necromancy"
|
ItemId = "staff_necromancy"
|
||||||
|
|
||||||
|
[node name="ItemMarker2D3" type="Marker2D" parent="."]
|
||||||
|
position = Vector2(214, 83)
|
||||||
|
script = ExtResource("3_v1tlc")
|
||||||
|
ItemId = "x3"
|
||||||
|
|
||||||
|
[node name="ItemMarker2D4" type="Marker2D" parent="."]
|
||||||
|
position = Vector2(366, 90)
|
||||||
|
script = ExtResource("3_v1tlc")
|
||||||
|
ItemId = "necromancy"
|
||||||
|
|
||||||
[node name="ItemMarker2D2" type="Marker2D" parent="."]
|
[node name="ItemMarker2D2" type="Marker2D" parent="."]
|
||||||
position = Vector2(321, 118)
|
position = Vector2(321, 118)
|
||||||
script = ExtResource("3_v1tlc")
|
script = ExtResource("3_v1tlc")
|
||||||
|
|
|
@ -17,6 +17,7 @@ collision_mask = 34
|
||||||
angular_damp = -1.0
|
angular_damp = -1.0
|
||||||
script = ExtResource("1_w8hhv")
|
script = ExtResource("1_w8hhv")
|
||||||
_numberSlots = 5
|
_numberSlots = 5
|
||||||
|
_fireSequentially = true
|
||||||
FiringIntervalAsMillisecond = 300
|
FiringIntervalAsMillisecond = 300
|
||||||
_recoilStrength = 5
|
_recoilStrength = 5
|
||||||
UniqueIcon = ExtResource("3_31iau")
|
UniqueIcon = ExtResource("3_31iau")
|
||||||
|
|
|
@ -33,12 +33,23 @@ public interface ISpell
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="projectileWeapon"></param>
|
/// <param name="projectileWeapon"></param>
|
||||||
void RestoreWeapon(ProjectileWeapon projectileWeapon);
|
void RestoreWeapon(ProjectileWeapon projectileWeapon);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Modify the projectile</para>
|
/// <para>Modify the projectile</para>
|
||||||
/// <para>修改抛射体</para>
|
/// <para>修改抛射体</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="projectile"></param>
|
/// <param name="index">
|
||||||
void ModifyProjectile(Projectile projectile);
|
///<para>What is the current projectile? For example, a weapon can fire three projectiles at once, with indexes 0,1,2</para>
|
||||||
|
///<para>当前抛射体是第几个?例如:武器可一下发射3个抛射体,索引为0,1,2</para>
|
||||||
|
/// </param>
|
||||||
|
/// <param name="projectile">
|
||||||
|
///<para>Projectile object</para>
|
||||||
|
///<para>抛射体对象</para>
|
||||||
|
/// </param>
|
||||||
|
/// <param name="velocity">
|
||||||
|
///<para>The velocity of the projectile</para>
|
||||||
|
///<para>抛射体的飞行速度</para>
|
||||||
|
/// </param>
|
||||||
|
void ModifyProjectile(int index,Projectile projectile, ref Vector2 velocity);
|
||||||
|
|
||||||
}
|
}
|
82
scripts/spell/MultipleFireSpell.cs
Normal file
82
scripts/spell/MultipleFireSpell.cs
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
using ColdMint.scripts.projectile;
|
||||||
|
using ColdMint.scripts.utils;
|
||||||
|
using ColdMint.scripts.weapon;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace ColdMint.scripts.spell;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>MultipleFireSpell</para>
|
||||||
|
/// <para>多重射击法术</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
///<para>Use this spell to create shotgun effects</para>
|
||||||
|
///<para>通过此法术打造霰弹枪的效果</para>
|
||||||
|
/// </remarks>
|
||||||
|
public partial class MultipleFireSpell : SpellPickAble
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>How many projectiles are generated per fire</para>
|
||||||
|
/// <para>每次开火生成多少个抛射体</para>
|
||||||
|
/// </summary>
|
||||||
|
[Export]
|
||||||
|
public int NumberOfProjectiles { get; set; } = 3;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>RandomAngle</para>
|
||||||
|
/// <para>随机角度</para>
|
||||||
|
/// </summary>
|
||||||
|
[Export]
|
||||||
|
public bool RandomAngle { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>Unit radian</para>
|
||||||
|
/// <para>单位弧度</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
///<para>Unit radian of correction for the projectile Angle.Suppose there are three bullets fired at once, and this is the arc between the two bullets.</para>
|
||||||
|
///<para>对抛射体角度修正的单位弧度。假定有三颗子弹一次发射,这是两颗子弹之间的弧度。</para>
|
||||||
|
/// </remarks>
|
||||||
|
[Export]
|
||||||
|
public float UnitRadian { get; set; } = 0.069813f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>initial Radian</para>
|
||||||
|
/// <para>起始弧度</para>
|
||||||
|
/// </summary>
|
||||||
|
///<remarks>
|
||||||
|
///<para>The Angle of the first bullet, and subsequent bullets will be offset in unit radians.</para>
|
||||||
|
///<para>第一颗子弹的角度,随后的子弹会以单位弧度偏移。</para>
|
||||||
|
/// </remarks>
|
||||||
|
private float _initialRadian;
|
||||||
|
private float _maxRadian;
|
||||||
|
private int _oldNumberOfProjectiles;
|
||||||
|
public override void ModifyWeapon(ProjectileWeapon projectileWeapon)
|
||||||
|
{
|
||||||
|
base.ModifyWeapon(projectileWeapon);
|
||||||
|
_oldNumberOfProjectiles = projectileWeapon.NumberOfProjectiles;
|
||||||
|
projectileWeapon.NumberOfProjectiles = NumberOfProjectiles;
|
||||||
|
_initialRadian = -(NumberOfProjectiles / 2f * UnitRadian);
|
||||||
|
_maxRadian = NumberOfProjectiles * UnitRadian;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RestoreWeapon(ProjectileWeapon projectileWeapon)
|
||||||
|
{
|
||||||
|
base.RestoreWeapon(projectileWeapon);
|
||||||
|
projectileWeapon.NumberOfProjectiles = _oldNumberOfProjectiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ModifyProjectile(int index, Projectile projectile, ref Vector2 velocity)
|
||||||
|
{
|
||||||
|
base.ModifyProjectile(index, projectile, ref velocity);
|
||||||
|
if (RandomAngle)
|
||||||
|
{
|
||||||
|
velocity = velocity.Rotated(_initialRadian + _maxRadian * RandomUtils.Instance.NextSingle());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
velocity = velocity.Rotated(_initialRadian + UnitRadian * index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -38,17 +38,17 @@ public partial class SpellPickAble : PickAbleTemplate, ISpell
|
||||||
return _projectileScene;
|
return _projectileScene;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyWeapon(ProjectileWeapon projectileWeapon)
|
public virtual void ModifyWeapon(ProjectileWeapon projectileWeapon)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RestoreWeapon(ProjectileWeapon projectileWeapon)
|
public virtual void RestoreWeapon(ProjectileWeapon projectileWeapon)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyProjectile(Projectile projectile)
|
public virtual void ModifyProjectile(int index, Projectile projectile, ref Vector2 velocity)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,36 +216,57 @@ public partial class ProjectileWeapon : WeaponTemplate
|
||||||
LogCat.LogError("projectile_scene_is_null");
|
LogCat.LogError("projectile_scene_is_null");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (var i = spellScope[0]; i <= spellScope[1]; i++)
|
ModifyWeapon(spellScope);
|
||||||
{
|
|
||||||
var spell = _spells[i];
|
|
||||||
spell.ModifyWeapon(this);
|
|
||||||
}
|
|
||||||
for (var i = 0; i < NumberOfProjectiles; i++)
|
for (var i = 0; i < NumberOfProjectiles; i++)
|
||||||
{
|
{
|
||||||
var projectile = NodeUtils.InstantiatePackedScene<Projectile>(packedScene);
|
var projectile = NodeUtils.InstantiatePackedScene<Projectile>(packedScene);
|
||||||
if (projectile == null)
|
if (projectile == null)
|
||||||
{
|
{
|
||||||
LogCat.LogError("projectile_is_null");
|
LogCat.LogError("projectile_is_null");
|
||||||
|
RestoreWeapon(spellScope);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
var velocity = _marker2D.GlobalPosition.DirectionTo(enemyGlobalPosition) * projectile.Speed;
|
||||||
for (var s = spellScope[0]; s <= spellScope[1]; s++)
|
for (var s = spellScope[0]; s <= spellScope[1]; s++)
|
||||||
{
|
{
|
||||||
var spell = _spells[s];
|
var spell = _spells[s];
|
||||||
spell.ModifyProjectile(projectile);
|
spell.ModifyProjectile(i, projectile, ref velocity);
|
||||||
}
|
}
|
||||||
NodeUtils.CallDeferredAddChild(GameSceneDepend.ProjectileContainer, projectile);
|
NodeUtils.CallDeferredAddChild(GameSceneDepend.ProjectileContainer, projectile);
|
||||||
projectile.Owner = owner;
|
projectile.Owner = owner;
|
||||||
projectile.TargetNode = GameSceneDepend.TemporaryTargetNode;
|
projectile.TargetNode = GameSceneDepend.TemporaryTargetNode;
|
||||||
projectile.Velocity =
|
projectile.Velocity = velocity;
|
||||||
_marker2D.GlobalPosition.DirectionTo(enemyGlobalPosition) * projectile.Speed;
|
|
||||||
projectile.Position = _marker2D.GlobalPosition;
|
projectile.Position = _marker2D.GlobalPosition;
|
||||||
}
|
}
|
||||||
|
RestoreWeapon(spellScope);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>Modify weapon attributes</para>
|
||||||
|
/// <para>修改武器属性</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="spellScope"></param>
|
||||||
|
private void ModifyWeapon(int[] spellScope)
|
||||||
|
{
|
||||||
|
for (var i = spellScope[0]; i <= spellScope[1]; i++)
|
||||||
|
{
|
||||||
|
var spell = _spells[i];
|
||||||
|
spell.ModifyWeapon(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>Restores modifications to weapons</para>
|
||||||
|
/// <para>恢复对武器的修改</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="spellScope"></param>
|
||||||
|
private void RestoreWeapon(int[] spellScope)
|
||||||
|
{
|
||||||
for (var i = spellScope[0]; i <= spellScope[1]; i++)
|
for (var i = spellScope[0]; i <= spellScope[1]; i++)
|
||||||
{
|
{
|
||||||
var spell = _spells[i];
|
var spell = _spells[i];
|
||||||
spell.RestoreWeapon(this);
|
spell.RestoreWeapon(this);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
sprites/projectile/x3.png
Normal file
BIN
sprites/projectile/x3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 216 B |
34
sprites/projectile/x3.png.import
Normal file
34
sprites/projectile/x3.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://mb5yijtw7sw5"
|
||||||
|
path="res://.godot/imported/x3.png-096b2fc27f9da2412a5f72aad28677de.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://sprites/projectile/x3.png"
|
||||||
|
dest_files=["res://.godot/imported/x3.png-096b2fc27f9da2412a5f72aad28677de.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
Loading…
Reference in New Issue
Block a user