cirnogodot/addons/weapon_creator/WeaponCreatorPlugin.gd

231 lines
9.3 KiB
GDScript

@tool
extends EditorPlugin
# Editor plugin that provides a UI for creating 3D weapons with all required resources
# Adds a dock panel to the editor with input fields and a create button
var dock_instance: PanelContainer
func _enter_tree() -> void:
# Load the dock script and instantiate programmatically
var dock_script = load("res://addons/weapon_creator/WeaponCreatorDock.gd")
dock_instance = PanelContainer.new()
dock_instance.set_script(dock_script)
# Connect the create button signal from the dock
if dock_instance.has_signal("create_weapon_requested"):
dock_instance.create_weapon_requested.connect(_on_create_weapon_requested)
# Add the dock to the editor (bottom dock area)
add_control_to_bottom_panel(dock_instance, "Weapon Creator")
func _exit_tree() -> void:
# Cleanup when plugin is disabled
if dock_instance:
remove_control_from_bottom_panel(dock_instance)
dock_instance.queue_free()
func _on_create_weapon_requested(weapon_data: Dictionary) -> void:
# Extract data from the dictionary
var weapon_name: String = weapon_data.get("weapon_name", "New Weapon")
var weapon_item_key: String = weapon_data.get("weapon_item_key", "NEW_WEAPON")
var ammo_key: String = weapon_data.get("ammo_key", "")
var weapon_short_name: String = weapon_data.get("weapon_short_name", "NW-1")
var weapon_description: String = weapon_data.get("weapon_description", "A new weapon")
var default_bullet_path: String = weapon_data.get("default_bullet_path", "res://Resources/Bullets/simple_ice_bullet.tres")
# Weapon stats
var priority: int = weapon_data.get("priority", 10)
var ammo_per_shot: int = weapon_data.get("ammo_per_shot", 1)
var rate_of_fire: float = weapon_data.get("rate_of_fire", 0.2)
var bullet_capacity: int = weapon_data.get("bullet_capacity", 50)
var reload_time: float = weapon_data.get("reload_time", 1.0)
var infinite_ammo: bool = weapon_data.get("infinite_ammo", false)
var recharge_time: float = weapon_data.get("recharge_time", 0.5)
var recharge_amount: int = weapon_data.get("recharge_amount", 5)
var bullets_per_shot: int = weapon_data.get("bullets_per_shot", 1)
var spread_angle: float = weapon_data.get("spread_angle", 0.0)
var random_spread: float = weapon_data.get("random_spread", 0.0)
# Build resource paths
var weapon_resource_path := "res://Resources/Weapons/" + weapon_item_key + ".tres"
var item_resource_path := "res://Resources/Items/" + weapon_item_key + "_Item.tres"
var items_database_path := "res://Resources/ItemsDatabase.tres"
# Feedback to the UI
dock_instance.call("add_log", "=== Starting Weapon Creation ===")
dock_instance.call("add_log", "Weapon Name: " + weapon_name)
dock_instance.call("add_log", "Item Key: " + weapon_item_key)
# Step 1: Create WeaponResource
if _create_weapon_resource(weapon_resource_path, weapon_name, weapon_item_key, ammo_key, default_bullet_path,
priority, ammo_per_shot, rate_of_fire, bullet_capacity, reload_time,
infinite_ammo, recharge_time, recharge_amount, bullets_per_shot,
spread_angle, random_spread):
dock_instance.call("add_log", "✓ Created WeaponResource at: " + weapon_resource_path, Color.GREEN)
else:
dock_instance.call("add_log", "✗ Failed to create WeaponResource", Color.RED)
dock_instance.call("set_creation_complete")
return
# Step 2: Create LootItem resource
if _create_loot_item_resource(item_resource_path, weapon_name, weapon_short_name,
weapon_description, weapon_item_key, weapon_resource_path):
dock_instance.call("add_log", "✓ Created LootItem at: " + item_resource_path, Color.GREEN)
else:
dock_instance.call("add_log", "✗ Failed to create LootItem", Color.RED)
dock_instance.call("set_creation_complete")
return
# Step 3: Add to ItemsDatabase
if _add_to_items_database(items_database_path, item_resource_path):
dock_instance.call("add_log", "✓ Added to ItemsDatabase", Color.GREEN)
else:
dock_instance.call("add_log", "✗ Failed to add to ItemsDatabase", Color.RED)
dock_instance.call("set_creation_complete")
return
dock_instance.call("add_log", "=== Weapon Creation Complete ===", Color.CYAN)
dock_instance.call("add_log", "Next steps:")
dock_instance.call("add_log", "1. Add sounds to the weapon resource")
dock_instance.call("add_log", "2. Add a sprite texture to the LootItem")
dock_instance.call("add_log", "3. Test the weapon in-game")
dock_instance.call("set_creation_complete")
# Refresh the filesystem
get_editor_interface().get_resource_filesystem().scan()
func _create_weapon_resource(path: String, weapon_name: String, item_key: String, ammo_key: String, bullet_path: String,
priority: int, ammo_per_shot: int, rate_of_fire: float, bullet_capacity: int,
reload_time: float, infinite_ammo: bool, recharge_time: float,
recharge_amount: int, bullets_per_shot: int, spread_angle: float,
random_spread: float) -> bool:
# Check if file already exists
if ResourceLoader.exists(path):
dock_instance.call("add_log", "Warning: WeaponResource already exists at " + path, Color.YELLOW)
return false
# Load the WeaponResource script
var weapon_script = load("res://Scripts/Resources/WeaponResource.cs")
if weapon_script == null:
dock_instance.call("add_log", "Error: Could not load WeaponResource.cs script", Color.RED)
return false
# Load the bullet resource
var bullet_resource = load(bullet_path)
if bullet_resource == null:
dock_instance.call("add_log", "Error: Could not load bullet resource from " + bullet_path, Color.RED)
return false
# Create new WeaponResource
var weapon_resource = Resource.new()
weapon_resource.set_script(weapon_script)
# Set basic properties
weapon_resource.set("Name", weapon_name)
weapon_resource.set("BulletData", bullet_resource)
weapon_resource.set("ItemKey", item_key)
weapon_resource.set("AmmoKey", ammo_key)
# Set weapon stats
weapon_resource.set("Priority", priority)
weapon_resource.set("AmmoPerShot", ammo_per_shot)
weapon_resource.set("RateOfFire", rate_of_fire)
weapon_resource.set("BulletCapacity", bullet_capacity)
weapon_resource.set("ReloadTime", reload_time)
weapon_resource.set("InfiniteAmmo", infinite_ammo)
weapon_resource.set("AutoReload", true)
weapon_resource.set("RechargeTime", recharge_time)
weapon_resource.set("RechargeAmount", recharge_amount)
weapon_resource.set("BulletsPerShot", bullets_per_shot)
weapon_resource.set("SpreadAngle", spread_angle)
weapon_resource.set("RandomSpread", random_spread)
# Save the resource
var err = ResourceSaver.save(weapon_resource, path)
if err != OK:
dock_instance.call("add_log", "Error saving WeaponResource: " + str(err), Color.RED)
return false
return true
func _create_loot_item_resource(path: String, item_name: String, short_name: String,
description: String, item_key: String,
weapon_resource_path: String) -> bool:
# Check if file already exists
if ResourceLoader.exists(path):
dock_instance.call("add_log", "Warning: LootItem already exists at " + path, Color.YELLOW)
return false
# Load the LootItem script
var loot_item_script = load("res://Scripts/Resources/LootItem.cs")
if loot_item_script == null:
dock_instance.call("add_log", "Error: Could not load LootItem.cs script", Color.RED)
return false
# Load the weapon resource we just created
var weapon_resource = load(weapon_resource_path)
if weapon_resource == null:
dock_instance.call("add_log", "Error: Could not load weapon resource from " + weapon_resource_path, Color.RED)
return false
# Create new LootItem
var loot_item = Resource.new()
loot_item.set_script(loot_item_script)
# Set properties
loot_item.set("ItemName", item_name)
loot_item.set("ShortName", short_name)
loot_item.set("ItemDescription", description)
loot_item.set("ItemKey", item_key)
loot_item.set("Item", 13) # ItemTypes.Weapon = 13
loot_item.set("WeaponData3D", weapon_resource)
loot_item.set("Amount", 1)
loot_item.set("Max", 1)
loot_item.set("Selectable", true)
loot_item.set("DropScenePath3D", "res://Scenes/Items/GenericItem3D.tscn")
# Save the resource
var err = ResourceSaver.save(loot_item, path)
if err != OK:
dock_instance.call("add_log", "Error saving LootItem: " + str(err), Color.RED)
return false
return true
func _add_to_items_database(database_path: String, item_resource_path: String) -> bool:
# Load the ItemsDatabase
var items_database = load(database_path)
if items_database == null:
dock_instance.call("add_log", "Error: Could not load ItemsDatabase from " + database_path, Color.RED)
return false
# Load the item we just created
var new_item = load(item_resource_path)
if new_item == null:
dock_instance.call("add_log", "Error: Could not load item from " + item_resource_path, Color.RED)
return false
# Get current items array
var loot_items = items_database.get("LootItems")
if loot_items == null:
dock_instance.call("add_log", "Error: Could not get LootItems array from database", Color.RED)
return false
# Check if item already exists
for item in loot_items:
if item.resource_path == item_resource_path:
dock_instance.call("add_log", "Warning: Item already exists in database", Color.YELLOW)
return false
# Append the new item
loot_items.append(new_item)
items_database.set("LootItems", loot_items)
# Save the database
var err = ResourceSaver.save(items_database, database_path)
if err != OK:
dock_instance.call("add_log", "Error saving ItemsDatabase: " + str(err), Color.RED)
return false
return true