diff --git a/apps/ci/ci-install-modules.sh b/apps/ci/ci-install-modules.sh index d584682ab..5987eaf7a 100755 --- a/apps/ci/ci-install-modules.sh +++ b/apps/ci/ci-install-modules.sh @@ -100,7 +100,8 @@ git clone --depth=1 --branch=main https://github.com/azerothcore/mod-system-vi git clone --depth=1 --branch=master https://github.com/azerothcore/mod-tic-tac-toe modules/mod-tic-tac-toe git clone --depth=1 --branch=master https://github.com/azerothcore/mod-top-arena modules/mod-top-arena git clone --depth=1 --branch=master https://github.com/azerothcore/mod-transmog modules/mod-transmog -git clone --depth=1 --branch=master https://github.com/azerothcore/mod-war-effort modules/mod-war-effort +# archived / outdated +#git clone --depth=1 --branch=master https://github.com/azerothcore/mod-war-effort modules/mod-war-effort git clone --depth=1 --branch=master https://github.com/azerothcore/mod-weekend-xp modules/mod-weekend-xp git clone --depth=1 --branch=master https://github.com/azerothcore/mod-who-logged modules/mod-who-logged git clone --depth=1 --branch=master https://github.com/azerothcore/mod-zone-difficulty modules/mod-zone-difficulty diff --git a/apps/startup-scripts/README.md b/apps/startup-scripts/README.md index 7b057581d..176ec3ed6 100644 --- a/apps/startup-scripts/README.md +++ b/apps/startup-scripts/README.md @@ -312,6 +312,9 @@ Services support two restart policies: # Edit configuration ./service-manager.sh edit world + +# Restore missing services from registry +./service-manager.sh restore ``` ## 🌍 Multiple Realms Setup @@ -384,22 +387,72 @@ cp examples/restarter-world.sh restarter-realm2.sh ## 🛠️ Service Management +### Service Registry and Persistence + +The service manager includes a comprehensive registry system that tracks all created services and enables automatic restoration: + +#### Service Registry Features + +- **Automatic Tracking**: All services are automatically registered when created +- **Cross-Reboot Persistence**: PM2 services are configured with startup persistence +- **Service Restoration**: Missing services can be detected and restored from registry +- **Migration Support**: Legacy service configurations can be migrated to the new format + +#### Using the Registry + +```bash +# Check for missing services and restore them +./service-manager.sh restore + +# List all registered services (includes status) +./service-manager.sh list + +# Services are automatically added to registry on creation +./service-manager.sh create auth authserver --bin-path /path/to/bin +``` + +#### Custom Configuration Directories + +You can customize where service configurations and PM2/systemd files are stored: + +```bash +# Set custom directories +export AC_SERVICE_CONFIG_DIR="/path/to/your/project/services" + +# Now all service operations will use these custom directories +./service-manager.sh create auth authserver --bin-path /path/to/bin +``` + +This is particularly useful for: +- **Version Control**: Keep service configurations in your project repository +- **Multiple Projects**: Separate service configurations per project +- **Team Collaboration**: Share service setups across development teams + +#### Migration from Legacy Format + +If you have existing services in the old format, use the migration script: + +```bash +# Migrate existing registry to new format +./migrate-registry.sh + +# The script will: +# - Detect old format automatically +# - Create a backup of the old registry +# - Convert to new format with proper tracking +# - Preserve all existing service information +``` + ### PM2 Services When using PM2 as the service provider: -```bash -# PM2-specific commands -pm2 list # List all PM2 processes -pm2 logs auth # View logs -pm2 monit # Real-time monitoring -pm2 restart auth # Restart service -pm2 delete auth # Remove service +* [PM2 CLI Documentation](https://pm2.io/docs/runtime/reference/pm2-cli/) -# Save PM2 configuration -pm2 save -pm2 startup # Auto-start on boot -``` +**Automatic PM2 Persistence**: The service manager automatically configures PM2 for persistence across reboots by: +- Running `pm2 startup` to set up the startup script +- Running `pm2 save` after each service creation/modification +- This ensures your services automatically start when the system reboots NOTE: pm2 cannot run tmux/screen sessions, but you can always use the `attach` command to connect to the service console because pm2 supports interactive mode. @@ -407,6 +460,12 @@ NOTE: pm2 cannot run tmux/screen sessions, but you can always use the `attach` c The startup scripts recognize several environment variables for configuration and runtime behavior: +#### Configuration Directory Variables + +- **`AC_SERVICE_CONFIG_DIR`**: Override the default configuration directory for services registry and configurations + - Default: `${XDG_CONFIG_HOME:-$HOME/.config}/azerothcore/services` + - Used for storing service registry and run-engine configurations + #### Service Detection Variables - **`AC_LAUNCHED_BY_PM2`**: Set to `1` when launched by PM2 (automatically set by service-manager) @@ -551,4 +610,18 @@ npm install -g pm2 sudo npm install -g pm2 ``` +#### 7. Registry Out of Sync +```bash +# If the service registry shows services that don't actually exist +``` +**Solution**: Use registry sync or restore +```bash +# Check and restore missing services (also cleans up orphaned entries) +./service-manager.sh restore + +# If you have a very old registry format, migrate it +./migrate-registry.sh +``` + + diff --git a/apps/startup-scripts/src/migrate-registry.sh b/apps/startup-scripts/src/migrate-registry.sh new file mode 100755 index 000000000..c5898794f --- /dev/null +++ b/apps/startup-scripts/src/migrate-registry.sh @@ -0,0 +1,144 @@ +#!/usr/bin/env bash + +# One-time migration script for service registry +# Converts old format to new format + +set -euo pipefail # Strict error handling + +CONFIG_DIR="${AC_SERVICE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/azerothcore/services}" +REGISTRY_FILE="$CONFIG_DIR/service_registry.json" +BACKUP_FILE="$CONFIG_DIR/service_registry.json.backup" + +# Colors +readonly YELLOW='\033[1;33m' +readonly GREEN='\033[0;32m' +readonly RED='\033[0;31m' +readonly BLUE='\033[0;34m' +readonly NC='\033[0m' + +echo -e "${BLUE}AzerothCore Service Registry Migration Tool${NC}" +echo "==============================================" + +# Check dependencies +if ! command -v jq >/dev/null 2>&1; then + echo -e "${RED}Error: jq is required but not installed. Please install jq package.${NC}" + exit 1 +fi + +# Create config directory if it doesn't exist +mkdir -p "$CONFIG_DIR" + +# Check if registry exists +if [ ! -f "$REGISTRY_FILE" ]; then + echo -e "${YELLOW}No registry file found. Nothing to migrate.${NC}" + exit 0 +fi + +# Validate JSON format +if ! jq empty "$REGISTRY_FILE" >/dev/null 2>&1; then + echo -e "${RED}Error: Registry file contains invalid JSON.${NC}" + echo "Please check the file: $REGISTRY_FILE" + exit 1 +fi + +# Check if it's already new format +if jq -e 'type == "array" and (length == 0 or .[0] | has("bin_path"))' "$REGISTRY_FILE" >/dev/null 2>&1; then + echo -e "${GREEN}Registry is already in new format. No migration needed.${NC}" + exit 0 +fi + +# Check if it's old format +if ! jq -e 'type == "array" and (length == 0 or .[0] | has("config"))' "$REGISTRY_FILE" >/dev/null 2>&1; then + echo -e "${YELLOW}Registry format not recognized. Manual review needed.${NC}" + echo "Current registry content:" + cat "$REGISTRY_FILE" + exit 1 +fi + +echo -e "${YELLOW}Old format detected. Starting migration...${NC}" + +# Create backup +if ! cp "$REGISTRY_FILE" "$BACKUP_FILE"; then + echo -e "${RED}Error: Failed to create backup file.${NC}" + exit 1 +fi +echo -e "${BLUE}Backup created: $BACKUP_FILE${NC}" + +# Convert to new format +echo "[]" > "$REGISTRY_FILE.new" + +services_migrated=0 +while IFS= read -r service; do + if [ -n "$service" ] && [ "$service" != "null" ]; then + name=$(echo "$service" | jq -r '.name // ""') + provider=$(echo "$service" | jq -r '.provider // ""') + type=$(echo "$service" | jq -r '.type // ""') + config=$(echo "$service" | jq -r '.config // ""') + + # Validate required fields + if [ -z "$name" ] || [ -z "$provider" ] || [ -z "$type" ]; then + echo -e "${YELLOW}Skipping invalid service entry: $service${NC}" + continue + fi + + echo -e "${YELLOW}Migrating service: $name${NC}" + + # Create new format entry with all required fields + new_entry=$(jq -n \ + --arg name "$name" \ + --arg provider "$provider" \ + --arg type "$type" \ + --arg bin_path "unknown" \ + --arg args "" \ + --arg created "$(date -Iseconds)" \ + --arg status "migrated" \ + --arg systemd_type "--user" \ + --arg restart_policy "always" \ + --arg session_manager "none" \ + --arg gdb_enabled "0" \ + --arg pm2_opts "" \ + --arg server_config "" \ + --arg legacy_config "$config" \ + '{ + name: $name, + provider: $provider, + type: $type, + bin_path: $bin_path, + args: $args, + created: $created, + status: $status, + systemd_type: $systemd_type, + restart_policy: $restart_policy, + session_manager: $session_manager, + gdb_enabled: $gdb_enabled, + pm2_opts: $pm2_opts, + server_config: $server_config, + legacy_config: $legacy_config + }') + + # Add to new registry with error checking + if ! jq --argjson entry "$new_entry" '. += [$entry]' "$REGISTRY_FILE.new" > "$REGISTRY_FILE.new.tmp"; then + echo -e "${RED}Error: Failed to add service $name to new registry${NC}" + rm -f "$REGISTRY_FILE.new" "$REGISTRY_FILE.new.tmp" + exit 1 + fi + mv "$REGISTRY_FILE.new.tmp" "$REGISTRY_FILE.new" + + services_migrated=$((services_migrated + 1)) + fi +done < <(jq -c '.[]?' "$BACKUP_FILE" 2>/dev/null || echo "") + +# Replace old registry with new one +if ! mv "$REGISTRY_FILE.new" "$REGISTRY_FILE"; then + echo -e "${RED}Error: Failed to replace old registry with new one${NC}" + exit 1 +fi + +echo -e "${GREEN}Migration completed successfully!${NC}" +echo -e "${BLUE}Services migrated: $services_migrated${NC}" +echo -e "${BLUE}Use 'service-manager.sh restore' to review and update services.${NC}" +echo -e "${YELLOW}Note: Migrated services have bin_path='unknown' and need manual recreation.${NC}" +echo "" +echo -e "${BLUE}To recreate services, use commands like:${NC}" +echo " ./service-manager.sh create auth authserver --provider pm2 --bin-path /path/to/your/bin" +echo " ./service-manager.sh create world worldserver --provider systemd --bin-path /path/to/your/bin" diff --git a/apps/startup-scripts/src/service-manager.sh b/apps/startup-scripts/src/service-manager.sh index 980dfbb3a..34dc4c4d5 100755 --- a/apps/startup-scripts/src/service-manager.sh +++ b/apps/startup-scripts/src/service-manager.sh @@ -4,6 +4,8 @@ # A unified interface for managing AzerothCore services with PM2 or systemd # This script provides commands to create, update, delete, and manage server instances +set -euo pipefail # Strict error handling + # Script location CURRENT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -11,16 +13,16 @@ SCRIPT_DIR="$CURRENT_PATH" ROOT_DIR="$(cd "$CURRENT_PATH/../../.." && pwd)" -# Configuration directory -CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/azerothcore/services" +# Configuration directory (can be overridden with AC_SERVICE_CONFIG_DIR) +CONFIG_DIR="${AC_SERVICE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/azerothcore/services}" REGISTRY_FILE="$CONFIG_DIR/service_registry.json" # Colors for output -YELLOW='\033[1;33m' -GREEN='\033[0;32m' -RED='\033[0;31m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color +readonly YELLOW='\033[1;33m' +readonly GREEN='\033[0;32m' +readonly RED='\033[0;31m' +readonly BLUE='\033[0;34m' +readonly NC='\033[0m' # No Color # Create config directory if it doesn't exist mkdir -p "$CONFIG_DIR" @@ -38,6 +40,198 @@ check_dependencies() { } } +# Registry management functions +function add_service_to_registry() { + local service_name="$1" + local provider="$2" + local service_type="$3" + local bin_path="$4" + local args="$5" + local systemd_type="$6" + local restart_policy="$7" + local session_manager="$8" + local gdb_enabled="$9" + local pm2_opts="${10}" + local server_config="${11}" + + # Remove any existing entry with the same service name to avoid duplicates + local tmp_file + tmp_file=$(mktemp) + jq --arg name "$service_name" 'map(select(.name != $name))' "$REGISTRY_FILE" > "$tmp_file" && mv "$tmp_file" "$REGISTRY_FILE" + + # Add the new entry to the registry + tmp_file=$(mktemp) + jq --arg name "$service_name" \ + --arg provider "$provider" \ + --arg type "$service_type" \ + --arg bin_path "$bin_path" \ + --arg args "$args" \ + --arg created "$(date -Iseconds)" \ + --arg systemd_type "$systemd_type" \ + --arg restart_policy "$restart_policy" \ + --arg session_manager "$session_manager" \ + --arg gdb_enabled "$gdb_enabled" \ + --arg pm2_opts "$pm2_opts" \ + --arg server_config "$server_config" \ + '. += [{"name": $name, "provider": $provider, "type": $type, "bin_path": $bin_path, "args": $args, "created": $created, "status": "active", "systemd_type": $systemd_type, "restart_policy": $restart_policy, "session_manager": $session_manager, "gdb_enabled": $gdb_enabled, "pm2_opts": $pm2_opts, "server_config": $server_config}]' \ + "$REGISTRY_FILE" > "$tmp_file" && mv "$tmp_file" "$REGISTRY_FILE" + + echo -e "${GREEN}Service '$service_name' added to registry${NC}" +} + +function remove_service_from_registry() { + local service_name="$1" + + if [ -f "$REGISTRY_FILE" ]; then + local tmp_file + tmp_file=$(mktemp) + jq --arg name "$service_name" \ + 'map(select(.name != $name))' \ + "$REGISTRY_FILE" > "$tmp_file" && mv "$tmp_file" "$REGISTRY_FILE" + echo -e "${GREEN}Service '$service_name' removed from registry${NC}" + fi +} + +function restore_missing_services() { + echo -e "${BLUE}Checking for missing services...${NC}" + + if [ ! -f "$REGISTRY_FILE" ] || [ ! -s "$REGISTRY_FILE" ]; then + echo -e "${YELLOW}No services registry found or empty${NC}" + return 0 + fi + + local missing_services=() + local services_count + services_count=$(jq length "$REGISTRY_FILE") + + if [ "$services_count" -eq 0 ]; then + echo -e "${YELLOW}No services registered${NC}" + return 0 + fi + + echo -e "${BLUE}Found $services_count registered services. Checking status...${NC}" + + # Check each service + for i in $(seq 0 $((services_count-1))); do + local service=$(jq -r ".[$i]" "$REGISTRY_FILE") + local name=$(echo "$service" | jq -r '.name') + local provider=$(echo "$service" | jq -r '.provider') + local service_type=$(echo "$service" | jq -r '.type') + local bin_path=$(echo "$service" | jq -r '.bin_path // "unknown"') + local args=$(echo "$service" | jq -r '.args // ""') + local status=$(echo "$service" | jq -r '.status // "active"') + local systemd_type=$(echo "$service" | jq -r '.systemd_type // "--user"') + local restart_policy=$(echo "$service" | jq -r '.restart_policy // "always"') + local session_manager=$(echo "$service" | jq -r '.session_manager // "none"') + local gdb_enabled=$(echo "$service" | jq -r '.gdb_enabled // "0"') + local pm2_opts=$(echo "$service" | jq -r '.pm2_opts // ""') + local server_config=$(echo "$service" | jq -r '.server_config // ""') + + local service_exists=false + + if [ "$provider" = "pm2" ]; then + if pm2 describe "$name" >/dev/null 2>&1; then + service_exists=true + fi + elif [ "$provider" = "systemd" ]; then + local user_unit="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user/$name.service" + local system_unit="/etc/systemd/system/$name.service" + if [ -f "$user_unit" ] || [ -f "$system_unit" ]; then + # Unit file present, you can also check if it is active + service_exists=true + else + # Unit file missing: service needs to be recreated! + service_exists=false + fi + fi + + if [ "$service_exists" = false ]; then + missing_services+=("$i") + echo -e "${YELLOW}Missing service: $name ($provider)${NC}" + else + echo -e "${GREEN}✓ Service $name ($provider) exists${NC}" + fi + done + + # Handle missing services + if [ ${#missing_services[@]} -eq 0 ]; then + echo -e "${GREEN}All registered services are present${NC}" + return 0 + fi + + echo -e "${YELLOW}Found ${#missing_services[@]} missing services${NC}" + + for index in "${missing_services[@]}"; do + local service=$(jq -r ".[$index]" "$REGISTRY_FILE") + local name=$(echo "$service" | jq -r '.name') + local provider=$(echo "$service" | jq -r '.provider') + local service_type=$(echo "$service" | jq -r '.type') + local bin_path=$(echo "$service" | jq -r '.bin_path') + local args=$(echo "$service" | jq -r '.args') + local systemd_type=$(echo "$service" | jq -r '.systemd_type // "--user"') + local restart_policy=$(echo "$service" | jq -r '.restart_policy // "always"') + local session_manager=$(echo "$service" | jq -r '.session_manager // "none"') + local gdb_enabled=$(echo "$service" | jq -r '.gdb_enabled // "0"') + local pm2_opts=$(echo "$service" | jq -r '.pm2_opts // ""') + local server_config=$(echo "$service" | jq -r '.server_config // ""') + + echo "" + echo -e "${YELLOW}Service '$name' ($provider) is missing${NC}" + echo " Type: $service_type" + echo " Status: $status" + + if [ "$bin_path" = "unknown" ] || [ "$bin_path" = "null" ] || [ "$status" = "migrated" ]; then + echo " Binary: " + echo " Args: " + echo "" + echo -e "${YELLOW}This service needs to be recreated manually:${NC}" + echo " $0 create $service_type $name --provider $provider --bin-path /path/to/your/bin" + else + echo " Binary: $bin_path" + echo " Args: $args" + fi + echo "" + + read -p "Do you want to (r)ecreate, (d)elete from registry, or (s)kip? [r/d/s]: " choice + + case "$choice" in + r|R|recreate) + if [ "$bin_path" = "unknown" ] || [ "$status" = "migrated" ]; then + echo -e "${YELLOW}Please recreate manually with full create command${NC}" + read -p "Remove this entry from registry? [y/n]: " remove_entry + if [[ "$remove_entry" =~ ^[Yy]$ ]]; then + remove_service_from_registry "$name" + fi + else + echo -e "${BLUE}Recreating service '$name'...${NC}" + if [ "$provider" = "pm2" ]; then + if [ "$args" != "null" ] && [ -n "$args" ]; then + pm2_create_service "$name" "$bin_path $args" "$restart_policy" $pm2_opts + else + pm2_create_service "$name" "$bin_path" "$restart_policy" $pm2_opts + fi + elif [ "$provider" = "systemd" ]; then + echo -e "${BLUE}Attempting to recreate systemd service '$name' automatically...${NC}" + if systemd_create_service "$name" "$bin_path $args" "$restart_policy" "$systemd_type" "$session_manager" "$gdb_enabled" "$server_config"; then + echo -e "${GREEN}Systemd service '$name' recreated successfully${NC}" + else + echo -e "${RED}Failed to recreate systemd service '$name'. Please recreate manually.${NC}" + echo " $0 create $name $service_type --provider systemd --bin-path $bin_path" + fi + fi + fi + ;; + d|D|delete) + echo -e "${BLUE}Removing '$name' from registry...${NC}" + remove_service_from_registry "$name" + ;; + s|S|skip|*) + echo -e "${BLUE}Skipping '$name'${NC}" + ;; + esac + done +} + # Check if PM2 is installed check_pm2() { if ! command -v pm2 >/dev/null 2>&1; then @@ -81,6 +275,7 @@ function print_help() { echo " $base_name update [options]" echo " $base_name delete " echo " $base_name list [provider]" + echo " $base_name restore" echo " $base_name start|stop|restart|status " echo " $base_name logs [--follow]" echo " $base_name attach " @@ -139,6 +334,9 @@ function print_help() { echo " $base_name attach worldserver-realm1" echo " $base_name list pm2" echo "" + echo " # Restore missing services from registry" + echo " $base_name restore" + echo "" echo "Notes:" echo " - Configuration editing modifies run-engine settings (GDB, session manager, etc.)" echo " - Use --server-config for the actual server configuration file" @@ -150,26 +348,13 @@ function print_help() { echo " - attach command automatically detects the configured session manager and connects appropriately" echo " - attach always provides interactive access to the server console" echo " - Use 'logs' command to view service logs without interaction" + echo " - restore command checks registry and helps recreate missing services" + echo "" + echo "Environment Variables:" + echo " AC_SERVICE_CONFIG_DIR - Override default config directory for services registry" } -function register_service() { - local service_name="$1" - local provider="$2" - local service_type="$3" - local config_file="$CONFIG_DIR/$service_name.conf" - - # Add to registry - local tmp_file=$(mktemp) - jq --arg name "$service_name" \ - --arg provider "$provider" \ - --arg type "$service_type" \ - --arg config "$config_file" \ - '. += [{"name": $name, "provider": $provider, "type": $type, "config": $config}]' \ - "$REGISTRY_FILE" > "$tmp_file" - mv "$tmp_file" "$REGISTRY_FILE" - - echo -e "${GREEN}Service $service_name registered successfully${NC}" -} + function validate_service_exists() { local service_name="$1" @@ -210,47 +395,42 @@ function validate_service_exists() { function sync_registry() { echo -e "${YELLOW}Syncing service registry with actual services...${NC}" - local services=$(jq -c '.[]' "$REGISTRY_FILE") - local tmp_file=$(mktemp) + if [ ! -f "$REGISTRY_FILE" ] || [ ! -s "$REGISTRY_FILE" ]; then + echo -e "${YELLOW}No services registry found or empty${NC}" + return 0 + fi - # Initialize with empty array + local services_count=$(jq length "$REGISTRY_FILE") + if [ "$services_count" -eq 0 ]; then + echo -e "${YELLOW}No services registered${NC}" + return 0 + fi + + local tmp_file=$(mktemp) echo "[]" > "$tmp_file" # Check each service in registry - while read -r service_info; do - if [ -n "$service_info" ]; then - local name=$(echo "$service_info" | jq -r '.name') - local provider=$(echo "$service_info" | jq -r '.provider') - - if validate_service_exists "$name" "$provider"; then - # Service exists, add it to the new registry - jq --argjson service "$service_info" '. += [$service]' "$tmp_file" > "$tmp_file.new" - mv "$tmp_file.new" "$tmp_file" - else - echo -e "${YELLOW}Service '$name' no longer exists. Removing from registry.${NC}" - # Don't add to new registry - fi + for i in $(seq 0 $((services_count-1))); do + local service=$(jq -r ".[$i]" "$REGISTRY_FILE") + local name=$(echo "$service" | jq -r '.name') + local provider=$(echo "$service" | jq -r '.provider') + + if validate_service_exists "$name" "$provider"; then + # Service exists, add it to the new registry + jq --argjson service "$service" '. += [$service]' "$tmp_file" > "$tmp_file.new" + mv "$tmp_file.new" "$tmp_file" + else + echo -e "${YELLOW}Service '$name' no longer exists. Removing from registry.${NC}" + # Don't add to new registry fi - done <<< "$services" + done # Replace registry with synced version mv "$tmp_file" "$REGISTRY_FILE" echo -e "${GREEN}Registry synchronized.${NC}" } -function unregister_service() { - local service_name="$1" - - # Remove from registry - local tmp_file=$(mktemp) - jq --arg name "$service_name" '. | map(select(.name != $name))' "$REGISTRY_FILE" > "$tmp_file" - mv "$tmp_file" "$REGISTRY_FILE" - - # Remove configuration file - rm -f "$CONFIG_DIR/$service_name.conf" - - echo -e "${GREEN}Service $service_name unregistered${NC}" -} + function get_service_info() { local service_name="$1" @@ -317,6 +497,15 @@ function pm2_create_service() { if eval "$pm2_cmd"; then echo -e "${GREEN}PM2 service '$service_name' created successfully${NC}" pm2 save + + # Setup PM2 startup for persistence across reboots + echo -e "${BLUE}Configuring PM2 startup for persistence...${NC}" + pm2 startup --auto >/dev/null 2>&1 || true + + # Add to registry (extract command and args from the full command) + local clean_command="$command$additional_args" + add_service_to_registry "$service_name" "pm2" "executable" "$command" "$additional_args" "" "$restart_policy" "none" "0" "$max_memory $max_restarts" "" + return 0 else echo -e "${RED}Failed to create PM2 service '$service_name'${NC}" @@ -334,8 +523,8 @@ function pm2_remove_service() { # Stop the service if it's running if pm2 describe "$service_name" >/dev/null 2>&1; then - pm2 stop "$service_name" 2>/dev/null || true - pm2 delete "$service_name" 2>/dev/null + pm2 stop "$service_name" 2>&1 || true + pm2 delete "$service_name" 2>&1 || true # Wait for PM2 to process the stop/delete command with timeout local timeout=10 @@ -357,8 +546,13 @@ function pm2_remove_service() { pm2 save echo -e "${GREEN}PM2 service '$service_name' stopped and removed${NC}" + + # Remove from registry + remove_service_from_registry "$service_name" else echo -e "${YELLOW}PM2 service '$service_name' not found or already removed${NC}" + # Still try to remove from registry in case it's orphaned + remove_service_from_registry "$service_name" fi return 0 @@ -391,6 +585,7 @@ function pm2_service_logs() { # Systemd service management functions function get_systemd_dir() { local type="$1" + if [ "$type" = "--system" ]; then echo "/etc/systemd/system" else @@ -403,17 +598,32 @@ function systemd_create_service() { local command="$2" local restart_policy="$3" local systemd_type="--user" + local bin_path="" + local gdb_enabled="0" + local server_config="" shift 3 check_systemd || return 1 - # Parse systemd type + # Parse systemd type and extract additional parameters while [[ $# -gt 0 ]]; do case "$1" in --system|--user) systemd_type="$1" shift ;; + --bin-path) + bin_path="$2" + shift 2 + ;; + --gdb-enabled) + gdb_enabled="$2" + shift 2 + ;; + --server-config) + server_config="$2" + shift 2 + ;; *) command+=" $1" shift @@ -421,6 +631,18 @@ function systemd_create_service() { esac done + # If bin_path is not provided, try to extract from command + if [ -z "$bin_path" ]; then + # Try to extract bin path from run-engine command + if [[ "$command" =~ run-engine[[:space:]]+start[[:space:]]+([^[:space:]]+) ]]; then + local binary_path="${BASH_REMATCH[1]}" + bin_path="$(dirname "$binary_path")" + else + # Fallback to current directory + bin_path="$(pwd)" + fi + fi + local systemd_dir=$(get_systemd_dir "$systemd_type") local service_file="$systemd_dir/$service_name.service" @@ -457,6 +679,11 @@ function systemd_create_service() { # Create service file echo -e "${YELLOW}Creating systemd service: $service_name${NC}" + # Ensure bin_path is absolute + if [[ ! "$bin_path" = /* ]]; then + bin_path="$(realpath "$bin_path")" + fi + if [ "$systemd_type" = "--system" ]; then # System service template (with User directive) cat > "$service_file" << EOF @@ -471,7 +698,7 @@ Restart=$restart_policy RestartSec=3 User=$(whoami) Group=$(id -gn) -WorkingDirectory=$(realpath "$bin_path") +WorkingDirectory=$bin_path StandardOutput=journal+console StandardError=journal+console @@ -490,7 +717,7 @@ Type=${service_type} ExecStart=$command Restart=$restart_policy RestartSec=3 -WorkingDirectory=$(realpath "$bin_path") +WorkingDirectory=$bin_path StandardOutput=journal+console StandardError=journal+console @@ -498,10 +725,6 @@ StandardError=journal+console WantedBy=default.target EOF fi - - if [ "$systemd_type" = "--system" ]; then - sed -i 's/WantedBy=default.target/WantedBy=multi-user.target/' "$service_file" - fi # Reload systemd and enable service if [ "$systemd_type" = "--system" ]; then @@ -513,6 +736,10 @@ EOF fi echo -e "${GREEN}Systemd service '$service_name' created successfully${NC}" + + # Add to registry + add_service_to_registry "$service_name" "systemd" "service" "$command" "" "$systemd_type" "$restart_policy" "$session_manager" "$gdb_enabled" "" "$server_config" + return 0 } @@ -572,6 +799,10 @@ function systemd_remove_service() { if [ "$removal_failed" = "true" ]; then echo -e "${YELLOW}Note: Service may still be running but configuration was removed${NC}" fi + + # Remove from registry + remove_service_from_registry "$service_name" + return 0 else echo -e "${RED}Failed to remove systemd service file '$service_file'${NC}" @@ -659,7 +890,7 @@ function create_service() { # Default values for run-engine configuration local provider="auto" - local bin_path="$BINPATH/bin" # get from config or environment + local bin_path="${BINPATH:-$ROOT_DIR/bin}" # get from config or environment local server_config="" local session_manager="none" local gdb_enabled="0" @@ -839,8 +1070,6 @@ EOF # Check if service creation was successful if [ "$service_creation_success" = "true" ]; then - # Register the service - register_service "$service_name" "$provider" "$service_type" echo -e "${GREEN}Service '$service_name' created successfully${NC}" echo -e "${BLUE}Run-engine config: $run_engine_config${NC}" @@ -880,14 +1109,20 @@ function update_service() { # Extract service information local provider=$(echo "$service_info" | jq -r '.provider') local service_type=$(echo "$service_info" | jq -r '.type') - local config_file=$(echo "$service_info" | jq -r '.config') + local config_file="$CONFIG_DIR/$service_name.conf" # Load current configuration + if [ ! -f "$config_file" ]; then + echo -e "${RED}Error: Service configuration file not found: $config_file${NC}" + return 1 + fi source "$config_file" # Load current run-engine configuration if [ -f "$RUN_ENGINE_CONFIG_FILE" ]; then source "$RUN_ENGINE_CONFIG_FILE" + else + echo -e "${YELLOW}Warning: Run-engine configuration file not found: $RUN_ENGINE_CONFIG_FILE${NC}" fi # Parse options to update @@ -1020,11 +1255,13 @@ function delete_service() { # Extract provider and config local provider=$(echo "$service_info" | jq -r '.provider') - local config_file=$(echo "$service_info" | jq -r '.config') + local config_file="$CONFIG_DIR/$service_name.conf" # Load configuration to get run-engine config file if [ -f "$config_file" ]; then source "$config_file" + else + echo -e "${YELLOW}Warning: Service configuration file not found: $config_file${NC}" fi echo -e "${YELLOW}Deleting service '$service_name' (provider: $provider)...${NC}" @@ -1048,8 +1285,9 @@ function delete_service() { echo -e "${GREEN}Removed run-engine config: $RUN_ENGINE_CONFIG_FILE${NC}" fi - # Unregister service - unregister_service "$service_name" + # Remove configuration file + rm -f "$config_file" + echo -e "${GREEN}Service '$service_name' deleted successfully${NC}" else echo -e "${RED}Failed to remove service '$service_name' from $provider${NC}" @@ -1166,7 +1404,7 @@ function edit_config() { fi # Get configuration file path - local config_file=$(echo "$service_info" | jq -r '.config') + local config_file="$CONFIG_DIR/$service_name.conf" # Load configuration to get run-engine config file source "$config_file" @@ -1191,7 +1429,7 @@ function attach_to_service() { # Extract provider local provider=$(echo "$service_info" | jq -r '.provider') - local config_file=$(echo "$service_info" | jq -r '.config') + local config_file="$CONFIG_DIR/$service_name.conf" # Load configuration to get run-engine config file if [ ! -f "$config_file" ]; then @@ -1206,6 +1444,11 @@ function attach_to_service() { echo -e "${RED}Error: Run-engine configuration file not found: $RUN_ENGINE_CONFIG_FILE${NC}" return 1 fi + + if [ ! -f "$RUN_ENGINE_CONFIG_FILE" ]; then + echo -e "${RED}Error: Run-engine configuration file not found: $RUN_ENGINE_CONFIG_FILE${NC}" + return 1 + fi source "$RUN_ENGINE_CONFIG_FILE" @@ -1264,9 +1507,22 @@ function attach_interactive_shell() { # For systemd without session manager, show helpful message local service_info=$(get_service_info "$service_name") - local config_file=$(echo "$service_info" | jq -r '.config') + local config_file="$CONFIG_DIR/$service_name.conf" + + # Check if config file exists before sourcing + if [ ! -f "$config_file" ]; then + echo -e "${RED}Error: Service configuration file not found: $config_file${NC}" + return 1 + fi source "$config_file" + + # Check if RUN_ENGINE_CONFIG_FILE exists before sourcing + if [ ! -f "$RUN_ENGINE_CONFIG_FILE" ]; then + echo -e "${RED}Error: Run-engine configuration file not found: $RUN_ENGINE_CONFIG_FILE${NC}" + return 1 + fi + source "$RUN_ENGINE_CONFIG_FILE" echo -e "${RED}Error: Cannot attach to systemd service '$service_name'${NC}" @@ -1375,6 +1631,9 @@ case "${1:-help}" in list) list_services "$2" ;; + restore) + restore_missing_services + ;; start|stop|restart|status) if [ $# -lt 2 ]; then echo -e "${RED}Error: Service name required for $1 command${NC}" diff --git a/data/sql/updates/db_world/2025_08_10_00.sql b/data/sql/updates/db_world/2025_08_10_00.sql new file mode 100644 index 000000000..cbbdd0811 --- /dev/null +++ b/data/sql/updates/db_world/2025_08_10_00.sql @@ -0,0 +1,4 @@ +-- DB update 2025_08_08_01 -> 2025_08_10_00 + +-- Remove Creature_addon tables from some Gargoyles. +DELETE FROM `creature_addon` WHERE (`guid` IN (100016, 100017, 100018, 100032, 100033, 100034, 100035, 100056, 100057, 100058, 100059, 100060, 100061)); diff --git a/data/sql/updates/db_world/2025_08_10_01.sql b/data/sql/updates/db_world/2025_08_10_01.sql new file mode 100644 index 000000000..0629204ae --- /dev/null +++ b/data/sql/updates/db_world/2025_08_10_01.sql @@ -0,0 +1,5 @@ +-- DB update 2025_08_10_00 -> 2025_08_10_01 +-- Delete Nerubian Chitin, Borean Leather, and Arctic Fur from loot table from various creatures in WotLK +DELETE from `creature_loot_template` WHERE `item` = 33568; +DELETE from `creature_loot_template` WHERE `item` = 44128; +DELETE from `creature_loot_template` WHERE `item` = 38558; diff --git a/data/sql/updates/db_world/2025_08_12_00.sql b/data/sql/updates/db_world/2025_08_12_00.sql new file mode 100644 index 000000000..c25388c09 --- /dev/null +++ b/data/sql/updates/db_world/2025_08_12_00.sql @@ -0,0 +1,42 @@ +-- DB update 2025_08_10_01 -> 2025_08_12_00 + +-- Set SmartAI (Wreckage A, B, C) +UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE (`entry`IN (188087, 188088, 188089)); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 1) AND (`entryorguid` IN (188087, 188088, 188089)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(188087, 1, 0, 0, 38, 0, 100, 0, 0, 1, 0, 0, 0, 0, 41, 0, 60, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Wreckage A - On Data Set 0 1 - Despawn Instant'), +(188088, 1, 0, 0, 38, 0, 100, 0, 0, 1, 0, 0, 0, 0, 41, 0, 60, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Wreckage B - On Data Set 0 1 - Despawn Instant'), +(188089, 1, 0, 0, 38, 0, 100, 0, 0, 1, 0, 0, 0, 0, 41, 0, 60, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Wreckage C - On Data Set 0 1 - Despawn Instant'); + +-- Set SmartAI (Fezzix Geartwist) +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 25849; + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 25849); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(25849, 0, 0, 0, 25, 0, 100, 512, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - On Reset - Set Event Phase 1'), +(25849, 0, 1, 2, 20, 1, 100, 0, 11894, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - On Quest \'Patching Up\' Finished - Say Line 0 (Phase 1)'), +(25849, 0, 2, 0, 61, 1, 100, 512, 0, 0, 0, 0, 0, 0, 80, 2584900, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - On Quest \'Patching Up\' Finished - Run Script (Phase 1)'), +(25849, 0, 3, 0, 40, 2, 100, 512, 11, 25849, 0, 0, 0, 0, 80, 2584901, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - On Point 11 of Path 25849 Reached - Run Script (Phase 2)'), +(25849, 0, 4, 5, 40, 2, 100, 512, 12, 25849, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - On Point 12 of Path 25849 Reached - Set Event Phase 1 (Phase 2)'), +(25849, 0, 5, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4.06662, 'Fezzix Geartwist - On Point 12 of Path 25849 Reached - Set Orientation 4.06662 (Phase 2)'); + +-- Set Timed Actionlist (Fezzix Geartwist) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9) AND (`entryorguid` IN (2584900, 2584901)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2584900, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Set Event Phase 2'), +(2584900, 9, 1, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 12, 26040, 1, 13000, 0, 0, 0, 8, 0, 0, 0, 0, 3481.33, 4099.85, 17.839, 3.35103, 'Fezzix Geartwist - Actionlist - Summon Creature \'Fezzix\'s Flying Machine\''), +(2584900, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 14, 60069, 188087, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Set Data 0 1'), +(2584900, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 14, 60080, 188088, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Set Data 0 1'), +(2584900, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 14, 60095, 188089, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Set Data 0 1'), +(2584900, 9, 5, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Say Line 1'), +(2584900, 9, 6, 0, 0, 0, 100, 0, 9000, 9000, 0, 0, 0, 0, 43, 0, 22719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Mount To Model 22719'), +(2584900, 9, 7, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Say Line 2'), +(2584900, 9, 8, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Set Fly On'), +(2584900, 9, 9, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 53, 0, 25849, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Start Waypoint Path 25849'), +(2584901, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 46419, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Cast \'Cosmetic - Explosion\''), +(2584901, 9, 1, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Dismount'), +(2584901, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Set Fly Off'), +(2584901, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 42963, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Cast \'Cosmetic - Combat Knockdown Self\''), +(2584901, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Say Line 3'), +(2584901, 9, 5, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fezzix Geartwist - Actionlist - Say Line 4'); diff --git a/data/sql/updates/db_world/2025_08_12_01.sql b/data/sql/updates/db_world/2025_08_12_01.sql new file mode 100644 index 000000000..0f712fbf3 --- /dev/null +++ b/data/sql/updates/db_world/2025_08_12_01.sql @@ -0,0 +1,6 @@ +-- DB update 2025_08_12_00 -> 2025_08_12_01 +-- Anub'ar Guardian - Sunder Armor, Sunder Armor(H) +DELETE FROM `spell_custom_attr` WHERE `spell_id` IN (53618, 59350); +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES +(53618, 4194304), +(59350, 4194304); diff --git a/data/sql/updates/db_world/2025_08_13_00.sql b/data/sql/updates/db_world/2025_08_13_00.sql new file mode 100644 index 000000000..719b7b844 --- /dev/null +++ b/data/sql/updates/db_world/2025_08_13_00.sql @@ -0,0 +1,8 @@ +-- DB update 2025_08_12_01 -> 2025_08_13_00 +-- Anub'ar Venomancer - Poison Bolt +DELETE FROM `spell_custom_attr` WHERE `spell_id` = 53617; +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES (53617, 4194304); + +-- Anub'ar Venomancer - Poison Bolt(H) +DELETE FROM `spell_custom_attr` WHERE `spell_id` = 59359; +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES (59359, 4194304); diff --git a/data/sql/updates/db_world/2025_08_14_00.sql b/data/sql/updates/db_world/2025_08_14_00.sql new file mode 100644 index 000000000..0323cc323 --- /dev/null +++ b/data/sql/updates/db_world/2025_08_14_00.sql @@ -0,0 +1,10 @@ +-- DB update 2025_08_13_00 -> 2025_08_14_00 +-- Allow Anub'ar warrior to use Strike ability. (Set the event_type 0 to "incombat update" instead of "out of combat update") +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 28732; +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28732) AND (`source_type` = 0) AND (`id` IN (0)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(28732, 0, 0, 0, 0, 0, 100, 0, 2000, 5000, 6000, 8000, 0, 0, 11, 52532, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, "Anub'ar Warrior - In Combat - Cast Strike"); + +-- Fix misplaced spell IDs in spelldifficulty for Skittering Infector's Acid Splash +UPDATE `spelldifficulty_dbc` SET `DifficultySpellID_1` = 52446 WHERE `ID` = 59363; +UPDATE `spelldifficulty_dbc` SET `DifficultySpellID_2` = 59363 WHERE `ID` = 59363; diff --git a/data/sql/updates/db_world/2025_08_18_00.sql b/data/sql/updates/db_world/2025_08_18_00.sql new file mode 100644 index 000000000..02662cf65 --- /dev/null +++ b/data/sql/updates/db_world/2025_08_18_00.sql @@ -0,0 +1,66 @@ +-- DB update 2025_08_14_00 -> 2025_08_18_00 +SET @CGUID := 82950; + +DELETE FROM `creature` WHERE `id1` IN (25090, 25091, 25092); +DELETE FROM `creature` WHERE `id1` IN (25090, 25091, 25092) AND `guid` BETWEEN @CGUID+0 AND @CGUID+57; +INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`, `CreateObject`) VALUES +(@CGUID+0 , 25090, 530, 0, 0, 1, 1, 0, 13196.1201171875, -7049.33642578125, 16.22812080383300781, 0.855211317539215087, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+1 , 25090, 530, 0, 0, 1, 1, 0, 13210.173828125 , -7052.376953125 , 16.07102394104003906, 4.572762489318847656, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+2 , 25090, 530, 0, 0, 1, 1, 0, 13202.560546875 , -7051.39697265625, 16.39847373962402343, 4.188790321350097656, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+3 , 25090, 530, 0, 0, 1, 1, 0, 13201.0830078125, -7048.72509765625, 13.21125602722167968, 0.191986218094825744, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+4 , 25090, 530, 0, 0, 1, 1, 0, 13199.25 , -7050.6953125 , 14.45721721649169921, 3.700098037719726562, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+5 , 25090, 530, 0, 0, 1, 1, 0, 13207.0126953125, -7053.20068359375, 15.47437477111816406, 2.740166902542114257, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+6 , 25090, 530, 0, 0, 1, 1, 0, 13246.345703125 , -7053.97412109375, 20.62376213073730468, 4.904375076293945312, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+7 , 25090, 530, 0, 0, 1, 1, 0, 13242.1611328125, -7054.7880859375 , 17.20347023010253906, 4.764749050140380859, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+8 , 25090, 530, 0, 0, 1, 1, 0, 13240.6982421875, -7053.22998046875, 14.11119270324707031, 4.97418832778930664 , 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+9 , 25090, 530, 0, 0, 1, 1, 0, 13235.609375 , -7053.92626953125, 15.19749736785888671, 5.934119224548339843, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+10, 25090, 530, 0, 0, 1, 1, 0, 13247.880859375 , -7055.54150390625, 18.45570755004882812, 0.575958669185638427, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+11, 25090, 530, 0, 0, 1, 1, 0, 13212.2255859375, -7054.658203125 , 17.02962112426757812, 6.108652114868164062, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+12, 25090, 530, 0, 0, 1, 1, 0, 13237.314453125 , -7053.35498046875, 18.92669677734375 , 3.351032257080078125, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+13, 25090, 530, 0, 0, 1, 1, 0, 13253.2548828125, -7054.8837890625 , 16.24456024169921875, 0.069813169538974761, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+14, 25090, 530, 0, 0, 1, 1, 0, 13274.5966796875, -7057.69384765625, 24.88401985168457031, 0.244346097111701965, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+15, 25090, 530, 0, 0, 1, 1, 0, 13264.31640625 , -7057.705078125 , 24.02816200256347656, 1.570796370506286621, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+16, 25090, 530, 0, 0, 1, 1, 0, 13261.1611328125, -7055.92529296875, 26.55978202819824218, 3.298672199249267578, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+17, 25090, 530, 0, 0, 1, 1, 0, 13255.951171875 , -7056.603515625 , 19.514129638671875 , 1.134464025497436523, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+18, 25090, 530, 0, 0, 1, 1, 0, 13262.6103515625, -7056.1162109375 , 22.68890190124511718, 4.520402908325195312, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+19, 25090, 530, 0, 0, 1, 1, 0, 13260.7216796875, -7056.51025390625, 24.51448440551757812, 5.899212837219238281, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), + +(@CGUID+20, 25091, 530, 0, 0, 1, 1, 0, 13330.6298828125, -6993.73974609375, 18.55262374877929687, 0.453785598278045654, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+21, 25091, 530, 0, 0, 1, 1, 0, 13329.9267578125, -6994.26416015625, 15.69489192962646484, 0.279252678155899047, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+22, 25091, 530, 0, 0, 1, 1, 0, 13317.7392578125, -6990.34716796875, 17.51109886169433593, 0.03490658476948738 , 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+23, 25091, 530, 0, 0, 1, 1, 0, 13317.330078125 , -6988.69384765625, 15.31146907806396484, 1.413716673851013183, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+24, 25091, 530, 0, 0, 1, 1, 0, 13325.728515625 , -6992.54296875 , 17.86301040649414062, 0.314159274101257324, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+25, 25091, 530, 0, 0, 1, 1, 0, 13321.5322265625, -6991.05859375 , 18.0410003662109375 , 3.473205089569091796, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+26, 25091, 530, 0, 0, 1, 1, 0, 13312.7392578125, -6989.04150390625, 16.80069160461425781, 3.03687286376953125 , 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+27, 25091, 530, 0, 0, 1, 1, 0, 13326.6171875 , -6991.60400390625, 15.73497295379638671, 3.874630928039550781, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+28, 25091, 530, 0, 0, 1, 1, 0, 13321.43359375 , -6992.02294921875, 15.16357707977294921, 1.850049018859863281, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+29, 25091, 530, 0, 0, 1, 1, 0, 13315.4501953125, -6990.5986328125 , 14.17850494384765625, 5.323254108428955078, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+30, 25091, 530, 0, 0, 1, 1, 0, 13351.2919921875, -6989.8095703125 , 14.9304962158203125 , 5.619960308074951171, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+31, 25091, 530, 0, 0, 1, 1, 0, 13348.5439453125, -6990.99853515625, 17.81970596313476562, 3.525565147399902343, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+32, 25091, 530, 0, 0, 1, 1, 0, 13359.8720703125, -6990.33447265625, 11.86795330047607421, 3.892084121704101562, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+33, 25091, 530, 0, 0, 1, 1, 0, 13363.31640625 , -6990.54541015625, 17.51730155944824218, 5.044001579284667968, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+34, 25091, 530, 0, 0, 1, 1, 0, 13357.7421875 , -6991.56103515625, 18.46755599975585937, 4.729842185974121093, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+35, 25091, 530, 0, 0, 1, 1, 0, 13361.9384765625, -6990.98291015625, 21.16696739196777343, 1.308996915817260742, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+36, 25091, 530, 0, 0, 1, 1, 0, 13357.88671875 , -6991.5693359375 , 15.036224365234375 , 1.850049018859863281, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+37, 25091, 530, 0, 0, 1, 1, 0, 13364.1953125 , -6991.95556640625, 18.6686553955078125 , 4.293509960174560546, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+38, 25091, 530, 0, 0, 1, 1, 0, 13374.556640625 , -6992.58837890625, 20.41219139099121093, 0.872664630413055419, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+39, 25091, 530, 0, 0, 1, 1, 0, 13372.1640625 , -6991.0869140625 , 22.58947563171386718, 4.904375076293945312, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+40, 25091, 530, 0, 0, 1, 1, 0, 13367.83203125 , -6992.177734375 , 11.62636184692382812, 2.530727386474609375, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+41, 25091, 530, 0, 0, 1, 1, 0, 13374.2861328125, -6991.216796875 , 18.20113945007324218, 5.026548385620117187, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+42, 25091, 530, 0, 0, 1, 1, 0, 13367.4873046875, -6992.15625 , 15.75841045379638671, 4.328416347503662109, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), + +(@CGUID+43, 25092, 530, 0, 0, 1, 1, 0, 13276.2861328125, -7148.3115234375 , 18.78717231750488281, 5.25344085693359375 , 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+44, 25092, 530, 0, 0, 1, 1, 0, 13267.578125 , -7146.2333984375 , 17.49614906311035156, 3.089232683181762695, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+45, 25092, 530, 0, 0, 1, 1, 0, 13273.84375 , -7146.33349609375, 11.37590885162353515, 0.314159274101257324, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+46, 25092, 530, 0, 0, 1, 1, 0, 13332.458984375 , -7149.9892578125 , 25.62369537353515625, 3.455751895904541015, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+47, 25092, 530, 0, 0, 1, 1, 0, 13324.3798828125, -7148.763671875 , 12.40258979797363281, 5.393067359924316406, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+48, 25092, 530, 0, 0, 1, 1, 0, 13283.3359375 , -7150.99072265625, 16.36432838439941406, 2.49582076072692871 , 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+49, 25092, 530, 0, 0, 1, 1, 0, 13306.396484375 , -7148.45556640625, 19.448272705078125 , 6.126105785369873046, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+50, 25092, 530, 0, 0, 1, 1, 0, 13323.8916015625, -7149.33056640625, 23.59075736999511718, 0.331612557172775268, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+51, 25092, 530, 0, 0, 1, 1, 0, 13314.80859375 , -7148.80078125 , 21.43866920471191406, 4.834561824798583984, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+52, 25092, 530, 0, 0, 1, 1, 0, 13308.7783203125, -7147.53515625 , 14.74446582794189453, 2.652900457382202148, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+53, 25092, 530, 0, 0, 1, 1, 0, 13336.470703125 , -7149.71533203125, 24.01339530944824218, 0.942477762699127197, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+54, 25092, 530, 0, 0, 1, 1, 0, 13279.6572265625, -7149.91162109375, 16.28713226318359375, 4.747295379638671875, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+55, 25092, 530, 0, 0, 1, 1, 0, 13285.5986328125, -7150.7265625 , 20.10992622375488281, 5.113814830780029296, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+56, 25092, 530, 0, 0, 1, 1, 0, 13315.0751953125, -7149.388671875 , 15.76729774475097656, 4.066617012023925781, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1), +(@CGUID+57, 25092, 530, 0, 0, 1, 1, 0, 13323.4755859375, -7150.04931640625, 19.51647567749023437, 2.251474618911743164, 180, 0, 0, 5468, 0, 0, 0, 0, 0, 49936, 1); diff --git a/data/sql/updates/db_world/2025_08_18_01.sql b/data/sql/updates/db_world/2025_08_18_01.sql new file mode 100644 index 000000000..2a0dbeedb --- /dev/null +++ b/data/sql/updates/db_world/2025_08_18_01.sql @@ -0,0 +1,4 @@ +-- DB update 2025_08_18_00 -> 2025_08_18_01 +DELETE FROM `spell_script_names` WHERE `spell_id` = 45848; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(45848, 'spell_kiljaeden_shield_of_the_blue'); diff --git a/data/sql/updates/db_world/2025_08_19_00.sql b/data/sql/updates/db_world/2025_08_19_00.sql new file mode 100644 index 000000000..a3589d86d --- /dev/null +++ b/data/sql/updates/db_world/2025_08_19_00.sql @@ -0,0 +1,66 @@ +-- DB update 2025_08_18_01 -> 2025_08_19_00 + +-- Remove Unit Flags from Roanauk Icemist (IMMUNE_TO_PC, IMMUNE_TO_NPC) +UPDATE `creature_template` SET `unit_flags` = `unit_flags` &~(256|512) WHERE (`entry` = 26654); + +-- Remove Unit Flags from Icemist Warriors (IMMUNE_TO_PC, IMMUNE_TO_NPC, STUNNED) +UPDATE `creature_template` SET `unit_flags` = `unit_flags` &~(256|512|262144) WHERE (`entry` = 26772); + +-- Update SmartAI (Roanauk Icemist) +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE (`entry` IN (26654, 26772)); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 26654); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(26654, 0, 0, 1, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Respawn - Set Flags Immune To Players & Immune To NPC\'s'), +(26654, 0, 1, 2, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 11, 26656, 10, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Respawn - Set Data 1 1'), +(26654, 0, 2, 3, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Respawn - Set Event Phase 1'), +(26654, 0, 3, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 11, 47273, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Respawn - Cast \'Icemist`s Prison\''), +(26654, 0, 4, 0, 1, 1, 100, 0, 5000, 30000, 120000, 150000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Out of Combat - Say Line 0 (Phase 1)'), +(26654, 0, 5, 0, 38, 0, 100, 513, 1, 1, 0, 0, 0, 0, 80, 2665400, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Data Set 1 1 - Run Script (No Repeat)'), +(26654, 0, 6, 0, 40, 0, 100, 512, 1, 0, 0, 0, 0, 0, 80, 2665401, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Point 1 of Path Any Reached - Run Script'), +(26654, 0, 7, 0, 38, 0, 100, 512, 2, 2, 0, 0, 0, 0, 80, 2665402, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - On Data Set 2 2 - Run Script'); + +-- Update Action List (Roanauk Icemist) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9) AND (`entryorguid` IN (2665400, 2665401)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2665400, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 28, 47273, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Remove Aura \'Icemist`s Prison\''), +(2665400, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 45, 2, 2, 0, 0, 0, 0, 9, 26656, 0, 200, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Set Data 2 2'), +(2665400, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Set Event Phase 2'), +(2665400, 9, 3, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 1'), +(2665400, 9, 4, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 53, 0, 26654, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Start Waypoint Path 26654'), +(2665401, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 2'), +(2665401, 9, 1, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 3'), +(2665401, 9, 2, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 19, 26608, 100, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 1'), +(2665401, 9, 3, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 11, 47378, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Cast \'Glory of the Ancestors\''), +(2665401, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 4'), +(2665401, 9, 5, 0, 0, 0, 100, 0, 7000, 7000, 0, 0, 0, 0, 19, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Remove Flags Immune To Players & Immune To NPC\'s'), +(2665401, 9, 6, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 11, 47379, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Cast \'Icemist`s Blessing\''), +(2665401, 9, 7, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 5'), +(2665401, 9, 8, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 1, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 6'), +(2665401, 9, 9, 0, 0, 0, 100, 0, 4000, 4000, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 19, 26608, 100, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 2'), +(2665401, 9, 10, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 1, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Say Line 7'), +(2665401, 9, 11, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 19, 26608, 100, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Set Data 1 1'), +(2665401, 9, 12, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Set Home Position'), +(2665401, 9, 13, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 19, 26608, 0, 0, 0, 0, 0, 0, 0, 'Roanauk Icemist - Actionlist - Start Attacking'); + +-- Update SmartAI (Icemist Warriors) +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 26772); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(26772, 0, 0, 1, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 29266, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Icemist Warrior - On Respawn - Cast \'Permanent Feign Death\''), +(26772, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 18, 262912, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Icemist Warrior - On Respawn - Set Flags Immune To Players & Immune To NPC\'s & Stunned'), +(26772, 0, 2, 3, 8, 0, 100, 512, 47378, 0, 0, 0, 0, 0, 28, 29266, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Icemist Warrior - On Spellhit \'Glory of the Ancestors\' - Remove Aura \'Permanent Feign Death\''), +(26772, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 2677200, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Icemist Warrior - On Spellhit \'Glory of the Ancestors\' - Run Script'), +(26772, 0, 4, 0, 38, 0, 100, 512, 1, 1, 0, 0, 0, 0, 41, 5000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Icemist Warrior - On Data Set 1 1 - Despawn In 5000 ms'); + +-- Add Action List (Icemist Warriors) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2677200); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(2677200, 9, 0, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 12, 26676, 6, 6000, 0, 0, 0, 202, 5, 1, 1, 0, 0, 0, 0, 0, 'Icemist Warrior - Actionlist - Summon Creature \'Anub\'ar Invader\''), +(2677200, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 262912, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Icemist Warrior - Actionlist - Remove Flags Immune To Players & Immune To NPC\'s & Stunned'); + +-- Set Conditions for Icemist's Blessing +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` = 47379; +INSERT INTO `conditions`(`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13,3,47379,0,0,31,0,3,26654,0,0,0,0,'','Icemist\'s Blessing (47379) - target is Roanauk Icemist'), +(13,3,47379,0,1,31,0,3,26772,0,0,0,0,'','Icemist\'s Blessing (47379) - target is Icemist Warrior'), +(13,3,47379,0,2,9,0,12069,0,0,0,0,0,'','Icemist\'s Blessing (47379) - player has quest 12069 active'); diff --git a/data/sql/updates/db_world/2025_08_23_00.sql b/data/sql/updates/db_world/2025_08_23_00.sql new file mode 100644 index 000000000..064b7cb64 --- /dev/null +++ b/data/sql/updates/db_world/2025_08_23_00.sql @@ -0,0 +1,84 @@ +-- DB update 2025_08_19_00 -> 2025_08_23_00 +SET @GUID = 83113; + +DELETE FROM `creature` WHERE `id1` IN (3296, 5595, 15383, 15431, 15432, 15434, 15437, 15445, 15446, 15448, 15450, 15451, 15452, 15453, 15455, 15456, 15457, 15458, 15459, 15460, 15469, 15477, 15508, 15512, 15515, 15522, 15525, 15528, 15529, 15532, 15533, 15534, 15535, 15539, 15663, 15696, 15700, 15701, 15702, 15703, 15704, 15707, 15708, 15709, 15731, 15733, 15734, 15735, 15736, 15737, 15738, 15739, 15761, 15762, 15763, 15764, 15765, 15766, 15767, 15768) AND `guid` BETWEEN @GUID AND @GUID+69; +INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +-- Ironforge +(@GUID+0, 15731, 0, 0, 0, 0, 0, 1, 1, 0, -4935.1743, -1197.6975, 501.62204, 2.460914134979248046, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Darnassus Commendation Officer +(@GUID+1, 15733, 0, 0, 0, 0, 0, 1, 1, 0, -4952.5264, -1176.9742, 501.63916, 5.393067359924316406, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Gnomeregan Commendation Officer +(@GUID+2, 15734, 0, 0, 0, 0, 0, 1, 1, 0, -4975.3374, -1196.7572, 501.74588, 1.884955525398254394, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Ironforge Commendation Officer +(@GUID+3, 15735, 0, 0, 0, 0, 0, 1, 1, 0, -4934.9854, -1214.3094, 501.7179, 3.333578824996948242, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Stormwind Commendation Officer +(@GUID+4, 5595, 0, 0, 0, 0, 0, 1, 1, 0, -4980.02, -1219.984, 501.75632, 3.822271108627319335, 300, 0, 0, 5228, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Ironforge Guard +(@GUID+5, 15539, 0, 0, 0, 0, 0, 1, 1, 0, -4981.2524, -1218.3779, 501.7562, 3.804817676544189453, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- General Zog +(@GUID+6, 5595, 0, 0, 0, 0, 0, 1, 1, 0, -4982.4688, -1216.806, 501.7562, 3.874630928039550781, 300, 0, 0, 5228, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Ironforge Guard +(@GUID+7, 15383, 0, 0, 0, 0, 0, 1, 1, 0, -4924.3657, -1222.7299, 501.71756, 3.926990747451782226, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Sergeant Stonebrow +(@GUID+8, 15431, 0, 0, 0, 0, 0, 1, 1, 0, -4914.172, -1227.4949, 501.73282, 3.59537816047668457, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Corporal Carnes +(@GUID+9, 15432, 0, 0, 0, 0, 0, 1, 1, 0, -4930.287, -1218.7476, 501.71875, 3.752457857131958007, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Dame Twinbraid +(@GUID+10, 15434, 0, 0, 0, 0, 0, 1, 1, 0, -4952.255, -1274.4495, 501.75662, 1.797689080238342285, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Private Draxlegauge +(@GUID+11, 15437, 0, 0, 0, 0, 0, 1, 1, 0, -4945.4204, -1282.0215, 501.75787, 1.029744267463684082, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Master Nightsong +(@GUID+12, 15445, 0, 0, 0, 0, 0, 1, 1, 0, -4948.3345, -1273.7974, 501.75522, 1.064650893211364746, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Sergeant Major Germaine +(@GUID+13, 15446, 0, 0, 0, 0, 0, 1, 1, 0, -4972.2017, -1169.0591, 501.72, 3.281219005584716796, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Bonnie Stoneflayer +(@GUID+14, 15448, 0, 0, 0, 0, 0, 1, 1, 0, -4966.0938, -1176.0596, 501.74265, 3.298672199249267578, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Private Porter +(@GUID+15, 15450, 0, 0, 0, 0, 0, 1, 1, 0, -4969.4565, -1180.2417, 501.7428, 3.246312379837036132, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Marta Finespindle +(@GUID+16, 15451, 0, 0, 0, 0, 0, 1, 1, 0, -4971.5747, -1151.5566, 501.73938, 3.560471534729003906, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Sentinel Silversky +(@GUID+17, 15452, 0, 0, 0, 0, 0, 1, 1, 0, -4979.116, -1149.51, 501.7331, 3.368485450744628906, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Nurse Stonefield +(@GUID+18, 15453, 0, 0, 0, 0, 0, 1, 1, 0, -4979.9287, -1142.1707, 501.7428, 3.682644605636596679, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Keeper Moonshade +(@GUID+19, 15455, 0, 0, 0, 0, 0, 1, 1, 0, -4938.0024, -1275.1202, 501.75195, 2.460914134979248046, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Slicky Gastronome +(@GUID+20, 15456, 0, 0, 0, 0, 0, 1, 1, 0, -4940.392, -1277.704, 501.7544, 1.989675283432006835, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Sarah Sadwhistle +(@GUID+21, 15457, 0, 0, 0, 0, 0, 1, 1, 0, -4933.8027, -1279.1617, 501.74948, 2.426007747650146484, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Huntress Swiftriver +(@GUID+22, 15663, 0, 0, 0, 0, 0, 1, 1, 0, -4917.319, -1224.8823, 501.7417, 4.327857494354248046, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Volunteer +(@GUID+23, 15663, 0, 0, 0, 0, 0, 1, 1, 0, -4944.852, -1277.7028, 501.75586, 4.258603572845458984, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Volunteer +(@GUID+24, 15663, 0, 0, 0, 0, 0, 1, 1, 0, -4966.2954, -1173.8835, 501.72675, 3.648972272872924804, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Volunteer +(@GUID+25, 15663, 0, 0, 0, 0, 0, 1, 1, 0, -4975.13, -1153.5369, 501.74008, 3.013503551483154296, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Volunteer +(@GUID+26, 15663, 0, 0, 0, 0, 0, 1, 1, 0, -4937.548, -1280.2931, 501.7544, 4.558997154235839843, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Volunteer +(@GUID+27, 15701, 0, 0, 0, 0, 0, 1, 1, 0, -4977.4976, -1172.4156, 501.7317, 2.282009840011596679, 300, 0, 0, 30520, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- Field Marshal Snowfall +-- Orgrimmar +(@GUID+28, 15736, 0, 0, 1, 0, 0, 1, 1, 0, 1584.7704, -4112.9443, 33.37767, 5.410520553588867187, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Orgrimmar Commendation Officer +(@GUID+29, 15737, 0, 0, 1, 0, 0, 1, 1, 0, 1618.4412, -4101.7646, 32.95245, 5.235987663269042968, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Darkspear Commendation Officer +(@GUID+30, 15738, 0, 0, 1, 0, 0, 1, 1, 0, 1660.3582, -4107.4517, 34.620274, 2.059488534927368164, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Undercity Commendation Officer +(@GUID+31, 15739, 0, 0, 1, 0, 0, 1, 1, 0, 1603.886, -4142.897, 33.78176, 2.443460941314697265, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Thunder Bluff Commendation Officer +(@GUID+32, 3296, 0, 0, 1, 0, 0, 1, 1, 0, 1628.9564, -4119.1763, 31.244139, 2.094395160675048828, 300, 0, 0, 5228, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Orgrimmar Grunt +(@GUID+33, 15458, 0, 0, 1, 0, 0, 1, 1, 0, 1630.693, -4118.458, 31.265778, 1.972222089767456054, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Commander Stronghammer +(@GUID+34, 3296, 0, 0, 1, 0, 0, 1, 1, 0, 1632.3059, -4117.596, 31.29346, 2.042035102844238281, 300, 0, 0, 5228, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Orgrimmar Grunt +(@GUID+35, 15522, 0, 0, 1, 0, 0, 1, 1, 0, 1593.2671, -4159.4404, 36.90244, 2.94960641860961914, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Sergeant Umala +(@GUID+36, 15533, 0, 0, 1, 0, 0, 1, 1, 0, 1643.4338, -4085.0864, 37.337215, 4.677482128143310546, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Bloodguard Rawtar +(@GUID+37, 15534, 0, 0, 1, 0, 0, 1, 1, 0, 1629.785, -4089.1484, 35.632874, 5.25344085693359375, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Fisherman Lin'do +(@GUID+38, 15535, 0, 0, 1, 0, 0, 1, 1, 0, 1634.1218, -4084.9915, 36.52574, 5.218534469604492187, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Chief Sharpclaw +(@GUID+39, 15459, 0, 0, 1, 0, 0, 1, 1, 0, 1650.3278, -4124.2856, 31.452269, 2.652900457382202148, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Miner Cromwell +(@GUID+40, 15460, 0, 0, 1, 0, 0, 1, 1, 0, 1665.7623, -4117.497, 34.37464, 2.443460941314697265, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Grunt Maug +(@GUID+41, 15469, 0, 0, 1, 0, 0, 1, 1, 0, 1655.7728, -4119.1626, 32.695107, 1.326450228691101074, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Senior Sergeant T'kelah +(@GUID+42, 15477, 0, 0, 1, 0, 0, 1, 1, 0, 1615.0131, -4145.532, 35.131996, 1.378810048103332519, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Herbalist Proudfeather +(@GUID+43, 15508, 0, 0, 1, 0, 0, 1, 1, 0, 1625.951, -4149.423, 36.395786, 1.902408838272094726, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Batrider Pele'keiki +(@GUID+44, 15512, 0, 0, 1, 0, 0, 1, 1, 0, 1633.2582, -4142.117, 34.70991, 2.111848354339599609, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Apothecary Jezel +(@GUID+45, 15515, 0, 0, 1, 0, 0, 1, 1, 0, 1588.1735, -4179.9014, 39.98489, 2.897246599197387695, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Skinner Jamani +(@GUID+46, 15525, 0, 0, 1, 0, 0, 1, 1, 0, 1595.7618, -4174.3965, 39.766666, 2.722713708877563476, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Doctor Serratus +(@GUID+47, 15528, 0, 0, 1, 0, 0, 1, 1, 0, 1580.1736, -4116.1064, 34.41577, 5.602506637573242187, 300, 0, 0, 13495, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Healer Longrunner +(@GUID+48, 15529, 0, 0, 1, 0, 0, 1, 1, 0, 1571.1464, -4118.6587, 36.584232, 5.026548385620117187, 300, 0, 0, 14355, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Lady Callow +(@GUID+49, 15532, 0, 0, 1, 0, 0, 1, 1, 0, 1565.0651, -4123.9863, 37.44075, 0, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Stoneguard Clayhoof +(@GUID+50, 15696, 0, 0, 1, 0, 0, 1, 1, 0, 1576.2423, -4118.5137, 35.26423, 4.112950801849365234, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Recruit +(@GUID+51, 15696, 0, 0, 1, 0, 0, 1, 1, 0, 1591.8158, -4162.673, 37.39431, 4.81041717529296875, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Recruit +(@GUID+52, 15696, 0, 0, 1, 0, 0, 1, 1, 0, 1639.2985, -4081.972, 37.58056, 4.678342819213867187, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Recruit +(@GUID+53, 15696, 0, 0, 1, 0, 0, 1, 1, 0, 1629.4264, -4142.979, 34.864754, 3.117774009704589843, 300, 0, 0, 4775, 0, 2, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Recruit +(@GUID+54, 15696, 0, 0, 1, 0, 0, 1, 1, 0, 1666.3688, -4109.401, 35.089664, 1.868425965309143066, 300, 0, 0, 4775, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- War Effort Recruit +(@GUID+55, 15700, 0, 0, 1, 0, 0, 1, 1, 0, 1581.5414, -4184.574, 39.5738, 1.563615918159484863, 300, 0, 0, 30520, 0, 0, 0, 0, 0, '', 61582, 2, NULL), -- Warlord Gorchuk + +-- War Effort Recruiters +(@GUID+56, 15702, 0, 0, 1, 0, 0, 1, 1, 0, -1209.5848, 100.22011, 134.661, 3.159045934677124023, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Senior Sergeant Taiga +(@GUID+57, 15703, 0, 0, 0, 0, 0, 1, 1, 0, 1572.5758, 272.70654, -43.01935, 5.026548385620117187, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Senior Sergeant Grimsford +(@GUID+58, 15704, 0, 0, 1, 0, 0, 1, 1, 0, 1653.0684, -4403.811, 18.581886, 4.450589656829833984, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Senior Sergeant Kai'jin +(@GUID+59, 15707, 0, 0, 0, 0, 0, 1, 1, 0, -4956.0864, -931.13306, 503.3468, 5.375614166259765625, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Master Sergeant Fizzlebolt +(@GUID+60, 15708, 0, 0, 0, 0, 0, 1, 1, 0, -8813.751, 654.0678, 96.16028, 4.834561824798583984, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Master Sergeant Maclure +(@GUID+61, 15709, 0, 0, 1, 0, 0, 1, 1, 0, 9945.1455, 2494.2393, 1317.5244, 4.206243515014648437, 300, 0, 0, 15260, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Master Sergeant Moonshadow +-- Commendation Officers +(@GUID+62, 15761, 0, 0, 1, 0, 0, 1, 1, 0, 1945.322, -4330.305, 22.101057, 3.50811171531677246, 300, 0, 0, 2914, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Vu'Shalay +(@GUID+63, 15762, 0, 0, 1, 0, 0, 1, 1, 0, 9965.52, 2533.7234, 1319.0049, 0.471238881349563598, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Lunalight +(@GUID+64, 15763, 0, 0, 0, 0, 0, 1, 1, 0, -4811.9756, -1264.849, 501.95117, 3.054326057434082031, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Porterhouse +(@GUID+65, 15764, 0, 0, 0, 0, 0, 1, 1, 0, -4814.475, -1055.5201, 502.26733, 6.213372230529785156, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Ironbeard +(@GUID+66, 15765, 0, 0, 1, 0, 0, 1, 1, 0, 1911.704, -4276.771, 31.655682, 4.886921882629394531, 300, 0, 0, 2914, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Redblade +(@GUID+67, 15766, 0, 0, 0, 0, 0, 1, 1, 0, -8859.14, 638.28687, 96.34692, 1.815142393112182617, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Maloof +(@GUID+68, 15767, 0, 0, 1, 0, 0, 1, 1, 0, -1246.4849, 74.262695, 128.36818, 5.026548385620117187, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 1, NULL), -- Officer Thunderstrider +(@GUID+69, 15768, 0, 0, 0, 0, 0, 1, 1, 0, 1587.8914, 279.28018, -43.019344, 4.852015495300292968, 300, 0, 0, 2614, 0, 0, 0, 0, 0, '', 61582, 1, NULL); -- Officer Gothena + +-- Old spawns +DELETE FROM `creature` WHERE `guid` IN (37, 2032, 6519, 6520, 25997, 32076, 46803) AND `id1` IN (14724, 15761, 15762, 15764, 15765, 15767, 15768); +DELETE FROM `creature_addon` WHERE `guid` IN (6519, 6520, 25997, 32076, 46803); diff --git a/data/sql/updates/db_world/2025_08_23_01.sql b/data/sql/updates/db_world/2025_08_23_01.sql new file mode 100644 index 000000000..d63bf23ff --- /dev/null +++ b/data/sql/updates/db_world/2025_08_23_01.sql @@ -0,0 +1,465 @@ +-- DB update 2025_08_23_00 -> 2025_08_23_01 +SET @EventID = 131, + @OGUID = 3639, + @CGUID = 83113; + +SET @AQWarAllianceBarsInitial = @EventID+0, + @AQWarAllianceBarsT1 = @EventID+1, + @AQWarAllianceBarsT2 = @EventID+2, + @AQWarAllianceBarsT3 = @EventID+3, + @AQWarAllianceBarsT4 = @EventID+4, + @AQWarAllianceBarsT5 = @EventID+5, + @AQWarAllianceHerbsInitial = @EventID+6, + @AQWarAllianceHerbsT1 = @EventID+7, + @AQWarAllianceHerbsT2 = @EventID+8, + @AQWarAllianceHerbsT3 = @EventID+9, + @AQWarAllianceHerbsT4 = @EventID+10, + @AQWarAllianceHerbsT5 = @EventID+11, + @AQWarAllianceSkinsInitial = @EventID+12, + @AQWarAllianceSkinsT1 = @EventID+13, + @AQWarAllianceSkinsT2 = @EventID+14, + @AQWarAllianceSkinsT3 = @EventID+15, + @AQWarAllianceSkinsT4 = @EventID+16, + @AQWarAllianceSkinsT5 = @EventID+17, + @AQWarAllianceBandagesInitial = @EventID+18, + @AQWarAllianceBandagesT1 = @EventID+19, + @AQWarAllianceBandagesT2 = @EventID+20, + @AQWarAllianceBandagesT3 = @EventID+21, + @AQWarAllianceBandagesT4 = @EventID+22, + @AQWarAllianceBandagesT5 = @EventID+23, + @AQWarAllianceCookedGoodsInitial = @EventID+24, + @AQWarAllianceCookedGoodsT1 = @EventID+25, + @AQWarAllianceCookedGoodsT2 = @EventID+26, + @AQWarAllianceCookedGoodsT3 = @EventID+27, + @AQWarAllianceCookedGoodsT4 = @EventID+28, + @AQWarAllianceCookedGoodsT5 = @EventID+29, + @AQWarHordeBarsInitial = @EventID+30, + @AQWarHordeBarsT1 = @EventID+31, + @AQWarHordeBarsT2 = @EventID+32, + @AQWarHordeBarsT3 = @EventID+33, + @AQWarHordeBarsT4 = @EventID+34, + @AQWarHordeBarsT5 = @EventID+35, + @AQWarHordeHerbsInitial = @EventID+36, + @AQWarHordeHerbsT1 = @EventID+37, + @AQWarHordeHerbsT2 = @EventID+38, + @AQWarHordeHerbsT3 = @EventID+39, + @AQWarHordeHerbsT4 = @EventID+40, + @AQWarHordeHerbsT5 = @EventID+41, + @AQWarHordeSkinsInitial = @EventID+42, + @AQWarHordeSkinsT1 = @EventID+43, + @AQWarHordeSkinsT2 = @EventID+44, + @AQWarHordeSkinsT3 = @EventID+45, + @AQWarHordeSkinsT4 = @EventID+46, + @AQWarHordeSkinsT5 = @EventID+47, + @AQWarHordeBandagesInitial = @EventID+48, + @AQWarHordeBandagesT1 = @EventID+49, + @AQWarHordeBandagesT2 = @EventID+50, + @AQWarHordeBandagesT3 = @EventID+51, + @AQWarHordeBandagesT4 = @EventID+52, + @AQWarHordeBandagesT5 = @EventID+53, + @AQWarHordeCookedGoodsInitial = @EventID+54, + @AQWarHordeCookedGoodsT1 = @EventID+55, + @AQWarHordeCookedGoodsT2 = @EventID+56, + @AQWarHordeCookedGoodsT3 = @EventID+57, + @AQWarHordeCookedGoodsT4 = @EventID+58, + @AQWarHordeCookedGoodsT5 = @EventID+59; + +DELETE FROM `game_event` WHERE `eventEntry` IN (@AQWarAllianceBarsInitial, @AQWarAllianceBarsT1, @AQWarAllianceBarsT2, @AQWarAllianceBarsT3, @AQWarAllianceBarsT4, @AQWarAllianceBarsT5, @AQWarAllianceHerbsInitial, @AQWarAllianceHerbsT1, @AQWarAllianceHerbsT2, @AQWarAllianceHerbsT3, @AQWarAllianceHerbsT4, @AQWarAllianceHerbsT5, @AQWarAllianceSkinsInitial, @AQWarAllianceSkinsT1, @AQWarAllianceSkinsT2, @AQWarAllianceSkinsT3, @AQWarAllianceSkinsT4, @AQWarAllianceSkinsT5, @AQWarAllianceBandagesInitial, @AQWarAllianceBandagesT1, @AQWarAllianceBandagesT2, @AQWarAllianceBandagesT3, @AQWarAllianceBandagesT4, @AQWarAllianceBandagesT5, @AQWarAllianceCookedGoodsInitial, @AQWarAllianceCookedGoodsT1, @AQWarAllianceCookedGoodsT2, @AQWarAllianceCookedGoodsT3, @AQWarAllianceCookedGoodsT4, @AQWarAllianceCookedGoodsT5, @AQWarHordeBarsInitial, @AQWarHordeBarsT1, @AQWarHordeBarsT2, @AQWarHordeBarsT3, @AQWarHordeBarsT4, @AQWarHordeBarsT5, @AQWarHordeHerbsInitial, @AQWarHordeHerbsT1, @AQWarHordeHerbsT2, @AQWarHordeHerbsT3, @AQWarHordeHerbsT4, @AQWarHordeHerbsT5, @AQWarHordeSkinsInitial, @AQWarHordeSkinsT1, @AQWarHordeSkinsT2, @AQWarHordeSkinsT3, @AQWarHordeSkinsT4, @AQWarHordeSkinsT5, @AQWarHordeBandagesInitial, @AQWarHordeBandagesT1, @AQWarHordeBandagesT2, @AQWarHordeBandagesT3, @AQWarHordeBandagesT4, @AQWarHordeBandagesT5, @AQWarHordeCookedGoodsInitial, @AQWarHordeCookedGoodsT1, @AQWarHordeCookedGoodsT2, @AQWarHordeCookedGoodsT3, @AQWarHordeCookedGoodsT4, @AQWarHordeCookedGoodsT5); +INSERT INTO `game_event` (`eventEntry`, `start_time`, `end_time`, `occurence`, `length`, `holiday`, `holidayStage`, `description`, `world_event`, `announce`) VALUES +(@AQWarAllianceBarsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bars Initial', 5, 2), +(@AQWarAllianceBarsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bars Tier 1', 5, 2), +(@AQWarAllianceBarsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bars Tier 2', 5, 2), +(@AQWarAllianceBarsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bars Tier 3', 5, 2), +(@AQWarAllianceBarsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bars Tier 4', 5, 2), +(@AQWarAllianceBarsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bars Tier 5', 5, 2), +(@AQWarAllianceHerbsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Herbs Initial', 5, 2), +(@AQWarAllianceHerbsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Herbs Tier 1', 5, 2), +(@AQWarAllianceHerbsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Herbs Tier 2', 5, 2), +(@AQWarAllianceHerbsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Herbs Tier 3', 5, 2), +(@AQWarAllianceHerbsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Herbs Tier 4', 5, 2), +(@AQWarAllianceHerbsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Herbs Tier 5', 5, 2), +(@AQWarAllianceSkinsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Skins Initial', 5, 2), +(@AQWarAllianceSkinsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Skins Tier 1', 5, 2), +(@AQWarAllianceSkinsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Skins Tier 2', 5, 2), +(@AQWarAllianceSkinsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Skins Tier 3', 5, 2), +(@AQWarAllianceSkinsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Skins Tier 4', 5, 2), +(@AQWarAllianceSkinsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Skins Tier 5', 5, 2), +(@AQWarAllianceBandagesInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bandages Initial', 5, 2), +(@AQWarAllianceBandagesT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bandages Tier 1', 5, 2), +(@AQWarAllianceBandagesT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bandages Tier 2', 5, 2), +(@AQWarAllianceBandagesT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bandages Tier 3', 5, 2), +(@AQWarAllianceBandagesT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bandages Tier 4', 5, 2), +(@AQWarAllianceBandagesT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Bandages Tier 5', 5, 2), +(@AQWarAllianceCookedGoodsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Cooked Goods Initial', 5, 2), +(@AQWarAllianceCookedGoodsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Cooked Goods Tier 1', 5, 2), +(@AQWarAllianceCookedGoodsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Cooked Goods Tier 2', 5, 2), +(@AQWarAllianceCookedGoodsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Cooked Goods Tier 3', 5, 2), +(@AQWarAllianceCookedGoodsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Cooked Goods Tier 4', 5, 2), +(@AQWarAllianceCookedGoodsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Alliance Cooked Goods Tier 5', 5, 2), +(@AQWarHordeBarsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bars Initial', 5, 2), +(@AQWarHordeBarsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bars Tier 1', 5, 2), +(@AQWarHordeBarsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bars Tier 2', 5, 2), +(@AQWarHordeBarsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bars Tier 3', 5, 2), +(@AQWarHordeBarsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bars Tier 4', 5, 2), +(@AQWarHordeBarsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bars Tier 5', 5, 2), +(@AQWarHordeHerbsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Herbs Initial', 5, 2), +(@AQWarHordeHerbsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Herbs Tier 1', 5, 2), +(@AQWarHordeHerbsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Herbs Tier 2', 5, 2), +(@AQWarHordeHerbsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Herbs Tier 3', 5, 2), +(@AQWarHordeHerbsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Herbs Tier 4', 5, 2), +(@AQWarHordeHerbsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Herbs Tier 5', 5, 2), +(@AQWarHordeSkinsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Skins Initial', 5, 2), +(@AQWarHordeSkinsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Skins Tier 1', 5, 2), +(@AQWarHordeSkinsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Skins Tier 2', 5, 2), +(@AQWarHordeSkinsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Skins Tier 3', 5, 2), +(@AQWarHordeSkinsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Skins Tier 4', 5, 2), +(@AQWarHordeSkinsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Skins Tier 5', 5, 2), +(@AQWarHordeBandagesInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bandages Initial', 5, 2), +(@AQWarHordeBandagesT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bandages Tier 1', 5, 2), +(@AQWarHordeBandagesT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bandages Tier 2', 5, 2), +(@AQWarHordeBandagesT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bandages Tier 3', 5, 2), +(@AQWarHordeBandagesT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bandages Tier 4', 5, 2), +(@AQWarHordeBandagesT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Bandages Tier 5', 5, 2), +(@AQWarHordeCookedGoodsInitial, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Cooked Goods Initial', 5, 2), +(@AQWarHordeCookedGoodsT1, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Cooked Goods Tier 1', 5, 2), +(@AQWarHordeCookedGoodsT2, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Cooked Goods Tier 2', 5, 2), +(@AQWarHordeCookedGoodsT3, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Cooked Goods Tier 3', 5, 2), +(@AQWarHordeCookedGoodsT4, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Cooked Goods Tier 4', 5, 2), +(@AQWarHordeCookedGoodsT5, '2000-01-01 14:00:00', '2000-01-01 14:00:00', 5184000, 2592000, 0, 0, 'Ahn''Qiraj War Effort - Horde Cooked Goods Tier 5', 5, 2); + +DELETE FROM `game_event_creature` WHERE `eventEntry` = 22 AND `guid` BETWEEN @CGUID AND @CGUID+69; +INSERT INTO `game_event_creature` (`eventEntry`, `guid`) VALUES +(22, @CGUID+0), +(22, @CGUID+1), +(22, @CGUID+2), +(22, @CGUID+3), +(22, @CGUID+4), +(22, @CGUID+5), +(22, @CGUID+6), +(22, @CGUID+7), +(22, @CGUID+8), +(22, @CGUID+9), +(22, @CGUID+10), +(22, @CGUID+11), +(22, @CGUID+12), +(22, @CGUID+13), +(22, @CGUID+14), +(22, @CGUID+15), +(22, @CGUID+16), +(22, @CGUID+17), +(22, @CGUID+18), +(22, @CGUID+19), +(22, @CGUID+20), +(22, @CGUID+21), +(22, @CGUID+22), +(22, @CGUID+23), +(22, @CGUID+24), +(22, @CGUID+25), +(22, @CGUID+26), +(22, @CGUID+27), +(22, @CGUID+28), +(22, @CGUID+29), +(22, @CGUID+30), +(22, @CGUID+31), +(22, @CGUID+32), +(22, @CGUID+33), +(22, @CGUID+34), +(22, @CGUID+35), +(22, @CGUID+36), +(22, @CGUID+37), +(22, @CGUID+38), +(22, @CGUID+39), +(22, @CGUID+40), +(22, @CGUID+41), +(22, @CGUID+42), +(22, @CGUID+43), +(22, @CGUID+44), +(22, @CGUID+45), +(22, @CGUID+46), +(22, @CGUID+47), +(22, @CGUID+48), +(22, @CGUID+49), +(22, @CGUID+50), +(22, @CGUID+51), +(22, @CGUID+52), +(22, @CGUID+53), +(22, @CGUID+54), +(22, @CGUID+55), +(22, @CGUID+56), +(22, @CGUID+57), +(22, @CGUID+58), +(22, @CGUID+59), +(22, @CGUID+60), +(22, @CGUID+61), +(22, @CGUID+62), +(22, @CGUID+63), +(22, @CGUID+64), +(22, @CGUID+65), +(22, @CGUID+66), +(22, @CGUID+67), +(22, @CGUID+68), +(22, @CGUID+69); + +DELETE FROM `game_event_creature` WHERE `eventEntry` = 22 AND `guid` IN (37, 2032, 6519, 6520, 25997, 32076, 46803); + +DELETE FROM `game_event_gameobject` WHERE `eventEntry` IN (@AQWarAllianceBarsInitial, @AQWarAllianceBarsT1, @AQWarAllianceBarsT2, @AQWarAllianceBarsT3, @AQWarAllianceBarsT4, @AQWarAllianceBarsT5, @AQWarAllianceHerbsInitial, @AQWarAllianceHerbsT1, @AQWarAllianceHerbsT2, @AQWarAllianceHerbsT3, @AQWarAllianceHerbsT4, @AQWarAllianceHerbsT5, @AQWarAllianceSkinsInitial, @AQWarAllianceSkinsT1, @AQWarAllianceSkinsT2, @AQWarAllianceSkinsT3, @AQWarAllianceSkinsT4, @AQWarAllianceSkinsT5, @AQWarAllianceBandagesInitial, @AQWarAllianceBandagesT1, @AQWarAllianceBandagesT2, @AQWarAllianceBandagesT3, @AQWarAllianceBandagesT4, @AQWarAllianceBandagesT5, @AQWarAllianceCookedGoodsInitial, @AQWarAllianceCookedGoodsT1, @AQWarAllianceCookedGoodsT2, @AQWarAllianceCookedGoodsT3, @AQWarAllianceCookedGoodsT4, @AQWarAllianceCookedGoodsT5, @AQWarHordeBarsInitial, @AQWarHordeBarsT1, @AQWarHordeBarsT2, @AQWarHordeBarsT3, @AQWarHordeBarsT4, @AQWarHordeBarsT5, @AQWarHordeHerbsInitial, @AQWarHordeHerbsT1, @AQWarHordeHerbsT2, @AQWarHordeHerbsT3, @AQWarHordeHerbsT4, @AQWarHordeHerbsT5, @AQWarHordeSkinsInitial, @AQWarHordeSkinsT1, @AQWarHordeSkinsT2, @AQWarHordeSkinsT3, @AQWarHordeSkinsT4, @AQWarHordeSkinsT5, @AQWarHordeBandagesInitial, @AQWarHordeBandagesT1, @AQWarHordeBandagesT2, @AQWarHordeBandagesT3, @AQWarHordeBandagesT4, @AQWarHordeBandagesT5, @AQWarHordeCookedGoodsInitial, @AQWarHordeCookedGoodsT1, @AQWarHordeCookedGoodsT2, @AQWarHordeCookedGoodsT3, @AQWarHordeCookedGoodsT4, @AQWarHordeCookedGoodsT5); +INSERT INTO `game_event_gameobject` (`eventEntry`, `guid`) VALUES +(@AQWarAllianceBarsInitial, @OGUID+19), +(@AQWarAllianceBarsT1, @OGUID+19), +(@AQWarAllianceBarsT1, @OGUID+20), +(@AQWarAllianceBarsT2, @OGUID+19), +(@AQWarAllianceBarsT2, @OGUID+20), +(@AQWarAllianceBarsT2, @OGUID+21), +(@AQWarAllianceBarsT3, @OGUID+19), +(@AQWarAllianceBarsT3, @OGUID+20), +(@AQWarAllianceBarsT3, @OGUID+21), +(@AQWarAllianceBarsT3, @OGUID+22), +(@AQWarAllianceBarsT4, @OGUID+19), +(@AQWarAllianceBarsT4, @OGUID+20), +(@AQWarAllianceBarsT4, @OGUID+21), +(@AQWarAllianceBarsT4, @OGUID+22), +(@AQWarAllianceBarsT4, @OGUID+23), +(@AQWarAllianceBarsT5, @OGUID+19), +(@AQWarAllianceBarsT5, @OGUID+20), +(@AQWarAllianceBarsT5, @OGUID+21), +(@AQWarAllianceBarsT5, @OGUID+22), +(@AQWarAllianceBarsT5, @OGUID+23), +(@AQWarAllianceBarsT5, @OGUID+24), +(@AQWarAllianceHerbsInitial, @OGUID+25), +(@AQWarAllianceHerbsT1, @OGUID+25), +(@AQWarAllianceHerbsT1, @OGUID+31), +(@AQWarAllianceHerbsT2, @OGUID+25), +(@AQWarAllianceHerbsT2, @OGUID+31), +(@AQWarAllianceHerbsT2, @OGUID+32), +(@AQWarAllianceHerbsT3, @OGUID+25), +(@AQWarAllianceHerbsT3, @OGUID+31), +(@AQWarAllianceHerbsT3, @OGUID+32), +(@AQWarAllianceHerbsT3, @OGUID+33), +(@AQWarAllianceHerbsT4, @OGUID+25), +(@AQWarAllianceHerbsT4, @OGUID+31), +(@AQWarAllianceHerbsT4, @OGUID+32), +(@AQWarAllianceHerbsT4, @OGUID+33), +(@AQWarAllianceHerbsT4, @OGUID+34), +(@AQWarAllianceHerbsT5, @OGUID+25), +(@AQWarAllianceHerbsT5, @OGUID+31), +(@AQWarAllianceHerbsT5, @OGUID+32), +(@AQWarAllianceHerbsT5, @OGUID+33), +(@AQWarAllianceHerbsT5, @OGUID+34), +(@AQWarAllianceHerbsT5, @OGUID+35), +(@AQWarAllianceSkinsInitial, @OGUID+36), +(@AQWarAllianceSkinsT1, @OGUID+36), +(@AQWarAllianceSkinsT1, @OGUID+37), +(@AQWarAllianceSkinsT2, @OGUID+36), +(@AQWarAllianceSkinsT2, @OGUID+37), +(@AQWarAllianceSkinsT2, @OGUID+38), +(@AQWarAllianceSkinsT3, @OGUID+36), +(@AQWarAllianceSkinsT3, @OGUID+37), +(@AQWarAllianceSkinsT3, @OGUID+38), +(@AQWarAllianceSkinsT3, @OGUID+39), +(@AQWarAllianceSkinsT4, @OGUID+36), +(@AQWarAllianceSkinsT4, @OGUID+37), +(@AQWarAllianceSkinsT4, @OGUID+38), +(@AQWarAllianceSkinsT4, @OGUID+39), +(@AQWarAllianceSkinsT4, @OGUID+40), +(@AQWarAllianceSkinsT5, @OGUID+36), +(@AQWarAllianceSkinsT5, @OGUID+37), +(@AQWarAllianceSkinsT5, @OGUID+38), +(@AQWarAllianceSkinsT5, @OGUID+39), +(@AQWarAllianceSkinsT5, @OGUID+40), +(@AQWarAllianceSkinsT5, @OGUID+41), +(@AQWarAllianceBandagesInitial, @OGUID+0), +(@AQWarAllianceBandagesT1, @OGUID+0), +(@AQWarAllianceBandagesT1, @OGUID+1), +(@AQWarAllianceBandagesT1, @OGUID+6), +(@AQWarAllianceBandagesT2, @OGUID+0), +(@AQWarAllianceBandagesT2, @OGUID+1), +(@AQWarAllianceBandagesT2, @OGUID+2), +(@AQWarAllianceBandagesT2, @OGUID+6), +(@AQWarAllianceBandagesT2, @OGUID+7), +(@AQWarAllianceBandagesT2, @OGUID+8), +(@AQWarAllianceBandagesT2, @OGUID+9), +(@AQWarAllianceBandagesT3, @OGUID+0), +(@AQWarAllianceBandagesT3, @OGUID+1), +(@AQWarAllianceBandagesT3, @OGUID+2), +(@AQWarAllianceBandagesT3, @OGUID+3), +(@AQWarAllianceBandagesT3, @OGUID+6), +(@AQWarAllianceBandagesT3, @OGUID+7), +(@AQWarAllianceBandagesT3, @OGUID+8), +(@AQWarAllianceBandagesT3, @OGUID+9), +(@AQWarAllianceBandagesT3, @OGUID+10), +(@AQWarAllianceBandagesT3, @OGUID+11), +(@AQWarAllianceBandagesT3, @OGUID+12), +(@AQWarAllianceBandagesT3, @OGUID+13), +(@AQWarAllianceBandagesT4, @OGUID+0), +(@AQWarAllianceBandagesT4, @OGUID+1), +(@AQWarAllianceBandagesT4, @OGUID+2), +(@AQWarAllianceBandagesT4, @OGUID+3), +(@AQWarAllianceBandagesT4, @OGUID+4), +(@AQWarAllianceBandagesT4, @OGUID+6), +(@AQWarAllianceBandagesT4, @OGUID+7), +(@AQWarAllianceBandagesT4, @OGUID+8), +(@AQWarAllianceBandagesT4, @OGUID+9), +(@AQWarAllianceBandagesT4, @OGUID+10), +(@AQWarAllianceBandagesT4, @OGUID+11), +(@AQWarAllianceBandagesT4, @OGUID+12), +(@AQWarAllianceBandagesT4, @OGUID+13), +(@AQWarAllianceBandagesT4, @OGUID+14), +(@AQWarAllianceBandagesT4, @OGUID+15), +(@AQWarAllianceBandagesT4, @OGUID+16), +(@AQWarAllianceBandagesT4, @OGUID+17), +(@AQWarAllianceBandagesT4, @OGUID+18), +(@AQWarAllianceBandagesT5, @OGUID+0), +(@AQWarAllianceBandagesT5, @OGUID+1), +(@AQWarAllianceBandagesT5, @OGUID+2), +(@AQWarAllianceBandagesT5, @OGUID+3), +(@AQWarAllianceBandagesT5, @OGUID+4), +(@AQWarAllianceBandagesT5, @OGUID+5), +(@AQWarAllianceBandagesT5, @OGUID+6), +(@AQWarAllianceBandagesT5, @OGUID+7), +(@AQWarAllianceBandagesT5, @OGUID+8), +(@AQWarAllianceBandagesT5, @OGUID+9), +(@AQWarAllianceBandagesT5, @OGUID+10), +(@AQWarAllianceBandagesT5, @OGUID+11), +(@AQWarAllianceBandagesT5, @OGUID+12), +(@AQWarAllianceBandagesT5, @OGUID+13), +(@AQWarAllianceBandagesT5, @OGUID+14), +(@AQWarAllianceBandagesT5, @OGUID+15), +(@AQWarAllianceBandagesT5, @OGUID+16), +(@AQWarAllianceBandagesT5, @OGUID+17), +(@AQWarAllianceBandagesT5, @OGUID+18), +(@AQWarAllianceBandagesT5, @OGUID+72), +(@AQWarAllianceBandagesT5, @OGUID+73), +(@AQWarAllianceBandagesT5, @OGUID+74), +(@AQWarAllianceBandagesT5, @OGUID+75), +(@AQWarAllianceBandagesT5, @OGUID+76), +(@AQWarAllianceBandagesT5, @OGUID+77), +(@AQWarAllianceBandagesT5, @OGUID+78), +(@AQWarAllianceBandagesT5, @OGUID+79), +(@AQWarAllianceBandagesT5, @OGUID+80), +(@AQWarAllianceBandagesT5, @OGUID+81), +(@AQWarAllianceCookedGoodsInitial, @OGUID+25), +(@AQWarAllianceCookedGoodsT1, @OGUID+25), +(@AQWarAllianceCookedGoodsT1, @OGUID+26), +(@AQWarAllianceCookedGoodsT2, @OGUID+25), +(@AQWarAllianceCookedGoodsT2, @OGUID+26), +(@AQWarAllianceCookedGoodsT2, @OGUID+27), +(@AQWarAllianceCookedGoodsT3, @OGUID+25), +(@AQWarAllianceCookedGoodsT3, @OGUID+26), +(@AQWarAllianceCookedGoodsT3, @OGUID+27), +(@AQWarAllianceCookedGoodsT3, @OGUID+28), +(@AQWarAllianceCookedGoodsT4, @OGUID+25), +(@AQWarAllianceCookedGoodsT4, @OGUID+26), +(@AQWarAllianceCookedGoodsT4, @OGUID+27), +(@AQWarAllianceCookedGoodsT4, @OGUID+28), +(@AQWarAllianceCookedGoodsT4, @OGUID+29), +(@AQWarAllianceCookedGoodsT5, @OGUID+25), +(@AQWarAllianceCookedGoodsT5, @OGUID+26), +(@AQWarAllianceCookedGoodsT5, @OGUID+27), +(@AQWarAllianceCookedGoodsT5, @OGUID+28), +(@AQWarAllianceCookedGoodsT5, @OGUID+29), +(@AQWarAllianceCookedGoodsT5, @OGUID+30), +(@AQWarHordeBarsInitial, @OGUID+48), +(@AQWarHordeBarsT1, @OGUID+48), +(@AQWarHordeBarsT1, @OGUID+49), +(@AQWarHordeBarsT2, @OGUID+48), +(@AQWarHordeBarsT2, @OGUID+49), +(@AQWarHordeBarsT2, @OGUID+50), +(@AQWarHordeBarsT3, @OGUID+48), +(@AQWarHordeBarsT3, @OGUID+49), +(@AQWarHordeBarsT3, @OGUID+50), +(@AQWarHordeBarsT3, @OGUID+51), +(@AQWarHordeBarsT4, @OGUID+48), +(@AQWarHordeBarsT4, @OGUID+49), +(@AQWarHordeBarsT4, @OGUID+50), +(@AQWarHordeBarsT4, @OGUID+51), +(@AQWarHordeBarsT4, @OGUID+52), +(@AQWarHordeBarsT5, @OGUID+48), +(@AQWarHordeBarsT5, @OGUID+49), +(@AQWarHordeBarsT5, @OGUID+50), +(@AQWarHordeBarsT5, @OGUID+51), +(@AQWarHordeBarsT5, @OGUID+52), +(@AQWarHordeBarsT5, @OGUID+53), +(@AQWarHordeHerbsInitial, @OGUID+60), +(@AQWarHordeHerbsT1, @OGUID+60), +(@AQWarHordeHerbsT1, @OGUID+61), +(@AQWarHordeHerbsT2, @OGUID+60), +(@AQWarHordeHerbsT2, @OGUID+61), +(@AQWarHordeHerbsT2, @OGUID+62), +(@AQWarHordeHerbsT3, @OGUID+60), +(@AQWarHordeHerbsT3, @OGUID+61), +(@AQWarHordeHerbsT3, @OGUID+62), +(@AQWarHordeHerbsT3, @OGUID+63), +(@AQWarHordeHerbsT4, @OGUID+60), +(@AQWarHordeHerbsT4, @OGUID+61), +(@AQWarHordeHerbsT4, @OGUID+62), +(@AQWarHordeHerbsT4, @OGUID+63), +(@AQWarHordeHerbsT4, @OGUID+64), +(@AQWarHordeHerbsT5, @OGUID+60), +(@AQWarHordeHerbsT5, @OGUID+61), +(@AQWarHordeHerbsT5, @OGUID+62), +(@AQWarHordeHerbsT5, @OGUID+63), +(@AQWarHordeHerbsT5, @OGUID+64), +(@AQWarHordeHerbsT5, @OGUID+65), +(@AQWarHordeSkinsInitial, @OGUID+66), +(@AQWarHordeSkinsT1, @OGUID+66), +(@AQWarHordeSkinsT1, @OGUID+67), +(@AQWarHordeSkinsT2, @OGUID+66), +(@AQWarHordeSkinsT2, @OGUID+67), +(@AQWarHordeSkinsT2, @OGUID+68), +(@AQWarHordeSkinsT3, @OGUID+66), +(@AQWarHordeSkinsT3, @OGUID+67), +(@AQWarHordeSkinsT3, @OGUID+68), +(@AQWarHordeSkinsT3, @OGUID+69), +(@AQWarHordeSkinsT4, @OGUID+66), +(@AQWarHordeSkinsT4, @OGUID+67), +(@AQWarHordeSkinsT4, @OGUID+68), +(@AQWarHordeSkinsT4, @OGUID+69), +(@AQWarHordeSkinsT4, @OGUID+70), +(@AQWarHordeSkinsT5, @OGUID+66), +(@AQWarHordeSkinsT5, @OGUID+67), +(@AQWarHordeSkinsT5, @OGUID+68), +(@AQWarHordeSkinsT5, @OGUID+69), +(@AQWarHordeSkinsT5, @OGUID+70), +(@AQWarHordeSkinsT5, @OGUID+71), +(@AQWarHordeBandagesInitial, @OGUID+42), +(@AQWarHordeBandagesT1, @OGUID+42), +(@AQWarHordeBandagesT1, @OGUID+43), +(@AQWarHordeBandagesT2, @OGUID+42), +(@AQWarHordeBandagesT2, @OGUID+43), +(@AQWarHordeBandagesT2, @OGUID+44), +(@AQWarHordeBandagesT3, @OGUID+42), +(@AQWarHordeBandagesT3, @OGUID+43), +(@AQWarHordeBandagesT3, @OGUID+44), +(@AQWarHordeBandagesT3, @OGUID+45), +(@AQWarHordeBandagesT4, @OGUID+42), +(@AQWarHordeBandagesT4, @OGUID+43), +(@AQWarHordeBandagesT4, @OGUID+44), +(@AQWarHordeBandagesT4, @OGUID+45), +(@AQWarHordeBandagesT4, @OGUID+46), +(@AQWarHordeBandagesT5, @OGUID+42), +(@AQWarHordeBandagesT5, @OGUID+43), +(@AQWarHordeBandagesT5, @OGUID+44), +(@AQWarHordeBandagesT5, @OGUID+45), +(@AQWarHordeBandagesT5, @OGUID+46), +(@AQWarHordeBandagesT5, @OGUID+47), +(@AQWarHordeCookedGoodsInitial, @OGUID+54), +(@AQWarHordeCookedGoodsT1, @OGUID+54), +(@AQWarHordeCookedGoodsT1, @OGUID+55), +(@AQWarHordeCookedGoodsT2, @OGUID+54), +(@AQWarHordeCookedGoodsT2, @OGUID+55), +(@AQWarHordeCookedGoodsT2, @OGUID+56), +(@AQWarHordeCookedGoodsT3, @OGUID+54), +(@AQWarHordeCookedGoodsT3, @OGUID+55), +(@AQWarHordeCookedGoodsT3, @OGUID+56), +(@AQWarHordeCookedGoodsT3, @OGUID+57), +(@AQWarHordeCookedGoodsT4, @OGUID+54), +(@AQWarHordeCookedGoodsT4, @OGUID+55), +(@AQWarHordeCookedGoodsT4, @OGUID+56), +(@AQWarHordeCookedGoodsT4, @OGUID+57), +(@AQWarHordeCookedGoodsT4, @OGUID+58), +(@AQWarHordeCookedGoodsT5, @OGUID+54), +(@AQWarHordeCookedGoodsT5, @OGUID+55), +(@AQWarHordeCookedGoodsT5, @OGUID+56), +(@AQWarHordeCookedGoodsT5, @OGUID+57), +(@AQWarHordeCookedGoodsT5, @OGUID+58), +(@AQWarHordeCookedGoodsT5, @OGUID+59); diff --git a/data/sql/updates/db_world/2025_08_23_02.sql b/data/sql/updates/db_world/2025_08_23_02.sql new file mode 100644 index 000000000..acc01795c --- /dev/null +++ b/data/sql/updates/db_world/2025_08_23_02.sql @@ -0,0 +1,103 @@ +-- DB update 2025_08_23_01 -> 2025_08_23_02 +SET @GUID = 3639; +-- Note: Some of these are CO2s, especially since there's some weird destroy/recreate thing going on on official, but I just noted them as CO1s for the time being. +DELETE FROM `gameobject` WHERE `id` IN (180598, 180674, 180675, 180676, 180677, 180678, 180679, 180680, 180681, 180692, 180693, 180694, 180695, 180696, 180714, 180780, 180781, 180782, 180783, 180784, 180800, 180801, 180802, 180803, 180804, 180805, 180806, 180807, 180808, 180809, 180812, 180813, 180814, 180815, 180816, 180817, 180818, 180819, 180820, 180821, 180822, 180823, 180826, 180827, 180828, 180829, 180830, 180831, 180832, 180833, 180834, 180835, 180836, 180837, 180838, 180839, 180840, 180841, 180842, 180843) AND `guid` BETWEEN @GUID AND @GUID+81; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES +-- Ironforge +-- Bandages +(@GUID+0, 180598, 0, 0, 0, 1, 1, -4971.5483, -1148.5706, 501.648, 2.2863789, 0, 0, 0.90996075, 0.4146944, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+1, 180674, 0, 0, 0, 1, 1, -4968.3267, -1152.889, 501.9254, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+2, 180675, 0, 0, 0, 1, 1, -4969.2095, -1143.8433, 509.2506, 2.2863789, 0, 0, 0.90996075, 0.4146944, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+3, 180676, 0, 0, 0, 1, 1, -4983.004, -1136.2194, 501.6594, 2.3038306, 0, 0, 0.91354465, 0.40673843, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+4, 180677, 0, 0, 0, 1, 1, -4975.6016, -1147.3348, 509.2504, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+5, 180678, 0, 0, 0, 1, 1, -4974.111, -1148.3993, 510.8475, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T5 +-- CrateAllianceFirstAid01 +(@GUID+6, 180714, 0, 0, 0, 1, 1, -4972.807, -1145.8307, 501.64996, 3.6128378, 0, 0, -0.9723692, 0.23344836, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+7, 180714, 0, 0, 0, 1, 1, -4976.2925, -1158.7479, 501.64252, 0.85521054, 0, 0, 0.41469288, 0.90996146, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+8, 180714, 0, 0, 0, 1, 1, -4979.9673, -1146.8904, 501.65506, 4.2062464, 0, 0, -0.86162853, 0.5075394, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+9, 180714, 0, 0, 0, 1, 1, -4972.857, -1145.8458, 502.8929, 2.1991146, 0, 0, 0.89100647, 0.45399064, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+10, 180714, 0, 0, 0, 1, 1, -4977.4546, -1157.944, 501.64926, 3.9269955, 0, 0, -0.92387867, 0.3826855, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+11, 180714, 0, 0, 0, 1, 1, -4985.743, -1137.5488, 501.6594, 3.5430236, 0, 0, -0.9799242, 0.19937038, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+12, 180714, 0, 0, 0, 1, 1, -4979.9263, -1139.9106, 501.65945, 1.3613561, 0, 0, 0.62932014, 0.77714616, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+13, 180714, 0, 0, 0, 1, 1, -4972.919, -1145.8206, 504.1289, 1.7627825, 0, 0, 0.77162457, 0.63607824, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+14, 180714, 0, 0, 0, 1, 1, -4976.9517, -1158.2965, 502.88937, 4.153885, 0, 0, -0.8746195, 0.48481005, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+15, 180714, 0, 0, 0, 1, 1, -4972.6714, -1152.6599, 509.25027, 0.3316107, 0, 0, 0.16504669, 0.98628575, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+16, 180714, 0, 0, 0, 1, 1, -4968.471, -1149.9625, 501.9254, 5.0265493, 0, 0, -0.58778477, 0.80901736, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+17, 180714, 0, 0, 0, 1, 1, -4979.914, -1139.9069, 502.9025, 1.4835281, 0, 0, 0.67558956, 0.7372779, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+18, 180714, 0, 0, 0, 1, 1, -4985.936, -1135.9319, 501.6594, 3.1590624, 0, 0, -0.99996185, 0.008734641, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+72, 180714, 0, 0, 0, 1, 1, -4972.6826, -1136.9497, 509.77707, 4.3807764, 0, 0, -0.8141155, 0.58070296, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+73, 180714, 0, 0, 0, 1, 1, -4979.8037, -1146.875, 502.89078, 3.7175536, 0, 0, -0.9588194, 0.28401646, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+74, 180714, 0, 0, 0, 1, 1, -4971.91, -1153.9872, 509.25027, 5.2359877, 0, 0, -0.5, 0.8660254, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+75, 180714, 0, 0, 0, 1, 1, -4978.415, -1159.3356, 501.64444, 3.0368383, 0, 0, 0.9986286, 0.052353222, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+76, 180714, 0, 0, 0, 1, 1, -4974.837, -1156.8785, 503.5236, 6.003934, 0, 0, -0.13917255, 0.9902682, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+77, 180714, 0, 0, 0, 1, 1, -4986.0234, -1136.7771, 502.90247, 3.1940022, 0, 0, -0.9996567, 0.026201647, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+78, 180714, 0, 0, 0, 1, 1, -4979.7725, -1139.9098, 504.1386, 5.98648, 0, 0, -0.14780903, 0.98901594, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+79, 180714, 0, 0, 0, 1, 1, -4968.3887, -1150.027, 503.16846, 0.36651757, 0, 0, 0.18223476, 0.983255, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+80, 180714, 0, 0, 0, 1, 1, -4972.4443, -1153.132, 510.49332, 5.2534423, 0, 0, -0.49242306, 0.87035596, 300, 0, 1, '', 61582, NULL), -- T5 +(@GUID+81, 180714, 0, 0, 0, 1, 1, -4984.3228, -1135.7563, 504.87466, 3.6302915, 0, 0, -0.97029495, 0.241925, 300, 0, 1, '', 61582, NULL), -- T5 +-- Bars +(@GUID+19, 180680, 0, 0, 0, 1, 1, -4913.854, -1225.9967, 501.6508, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+20, 180780, 0, 0, 0, 1, 1, -4913.729, -1225.9507, 501.6506, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+21, 180781, 0, 0, 0, 1, 1, -4913.737, -1225.9277, 501.65067, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+22, 180782, 0, 0, 0, 1, 1, -4913.723, -1225.9167, 501.65067, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+23, 180783, 0, 0, 0, 1, 1, -4913.71, -1225.9053, 501.65067, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+24, 180784, 0, 0, 0, 1, 1, -4913.7773, -1225.8594, 501.65082, 2.2863789, 0, 0, 0.90996075, 0.4146944, 300, 0, 1, '', 61582, NULL), -- T5 +-- Cooking +(@GUID+25, 180679, 0, 0, 0, 1, 1, -4937.2886, -1282.7358, 501.67215, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- Cooking/Herbs Initial +(@GUID+26, 180800, 0, 0, 0, 1, 1, -4937.282, -1282.8739, 501.67227, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+27, 180806, 0, 0, 0, 1, 1, -4937.136, -1282.895, 501.6721, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+28, 180807, 0, 0, 0, 1, 1, -4937.2856, -1282.869, 501.67227, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+29, 180808, 0, 0, 0, 1, 1, -4937.336, -1282.7858, 501.67227, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+30, 180809, 0, 0, 0, 1, 1, -4937.2197, -1282.8075, 501.67215, 2.2863789, 0, 0, 0.90996075, 0.4146944, 300, 0, 1, '', 61582, NULL), -- T5 +-- Herbs +(@GUID+31, 180801, 0, 0, 0, 1, 1, -4935.5796, -1284.82, 501.67105, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+32, 180802, 0, 0, 0, 1, 1, -4935.6045, -1284.8381, 501.6711, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+33, 180803, 0, 0, 0, 1, 1, -4935.594, -1284.833, 501.6711, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+34, 180804, 0, 0, 0, 1, 1, -4935.621, -1284.8282, 501.6711, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+35, 180805, 0, 0, 0, 1, 1, -4935.5576, -1284.8864, 501.67105, 2.2340178, 0, 0, 0.8987932, 0.43837282, 300, 0, 1, '', 61582, NULL), -- T5 +-- Skins +(@GUID+36, 180681, 0, 0, 0, 1, 1, -4958.5093, -1179.3196, 501.65945, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+37, 180692, 0, 0, 0, 1, 1, -4958.517, -1179.3344, 501.65945, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+38, 180693, 0, 0, 0, 1, 1, -4958.528, -1179.335, 501.65945, 2.2514734, 0, 0, 0.902585, 0.43051165, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+39, 180694, 0, 0, 0, 1, 1, -4958.526, -1179.3273, 501.65945, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+40, 180695, 0, 0, 0, 1, 1, -4958.5156, -1179.3286, 501.65945, 2.2689254, 0, 0, 0.9063072, 0.4226195, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+41, 180696, 0, 0, 0, 1, 1, -4958.5293, -1179.3357, 501.65945, 2.2863789, 0, 0, 0.90996075, 0.4146944, 300, 0, 1, '', 61582, NULL), -- T5 +-- Orgrimmar +-- Bandages +(@GUID+42, 180826, 1, 0, 0, 1, 1, 1579.3531, -4109.2544, 34.541737, 3.7524624, 0, 0, -0.9537163, 0.3007079, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+43, 180827, 1, 0, 0, 1, 1, 1579.3342, -4109.2476, 34.54871, 3.7175536, 0, 0, -0.9588194, 0.28401646, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+44, 180828, 1, 0, 0, 1, 1, 1579.321, -4109.278, 34.551514, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+45, 180829, 1, 0, 0, 1, 1, 1579.333, -4109.2837, 34.547028, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+46, 180830, 1, 0, 0, 1, 1, 1579.3325, -4109.2783, 34.547504, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+47, 180831, 1, 0, 0, 1, 1, 1579.331, -4109.2827, 34.54776, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T5 +-- Bars +(@GUID+48, 180838, 1, 0, 0, 1, 1, 1683.1149, -4134.354, 39.541912, 3.7175536, 0, 0, -0.9588194, 0.28401646, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+49, 180839, 1, 0, 0, 1, 1, 1683.0984, -4134.31, 39.539, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+50, 180840, 1, 0, 0, 1, 1, 1683.097, -4134.3, 39.538742, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+51, 180841, 1, 0, 0, 1, 1, 1683.1057, -4134.3135, 39.54028, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+52, 180842, 1, 0, 0, 1, 1, 1683.0347, -4134.3135, 39.52796, 3.7175536, 0, 0, -0.9588194, 0.28401646, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+53, 180843, 1, 0, 0, 1, 1, 1683.1418, -4134.3403, 39.54657, 3.7524624, 0, 0, -0.9537163, 0.3007079, 300, 0, 1, '', 61582, NULL), -- T5 +-- Cooking +(@GUID+54, 180832, 1, 0, 0, 1, 1, 1619.8307, -4092.4302, 34.51068, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+55, 180833, 1, 0, 0, 1, 1, 1619.8004, -4092.5334, 34.488815, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+56, 180834, 1, 0, 0, 1, 1, 1619.8002, -4092.5317, 34.489204, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+57, 180835, 1, 0, 0, 1, 1, 1619.8073, -4092.5269, 34.490135, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+58, 180836, 1, 0, 0, 1, 1, 1619.8062, -4092.5305, 34.48937, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+59, 180837, 1, 0, 0, 1, 1, 1619.8094, -4092.5217, 34.491196, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T5 +-- Herbs +(@GUID+60, 180818, 1, 0, 0, 1, 1, 1637.1053, -4147.2134, 36.04144, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+61, 180819, 1, 0, 0, 1, 1, 1637.1001, -4147.2534, 36.053123, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+62, 180820, 1, 0, 0, 1, 1, 1637.111, -4147.2534, 36.05357, 3.735006, 0, 0, -0.95630455, 0.29237235, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+63, 180821, 1, 0, 0, 1, 1, 1637.1099, -4147.2573, 36.054718, 3.7524624, 0, 0, -0.9537163, 0.3007079, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+64, 180822, 1, 0, 0, 1, 1, 1637.079, -4147.228, 36.04483, 3.7175536, 0, 0, -0.9588194, 0.28401646, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+65, 180823, 1, 0, 0, 1, 1, 1637.1013, -4147.226, 36.045063, 3.7175536, 0, 0, -0.9588194, 0.28401646, 300, 0, 1, '', 61582, NULL), -- T5 +-- Skins +(@GUID+66, 180812, 1, 0, 0, 1, 1, 1590.8248, -4155.328, 36.292576, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- Initial +(@GUID+67, 180813, 1, 0, 0, 1, 1, 1590.8755, -4155.335, 36.298023, 3.6826503, 0, 0, -0.9636297, 0.267241, 300, 0, 1, '', 61582, NULL), -- T1 +(@GUID+68, 180814, 1, 0, 0, 1, 1, 1590.8511, -4155.342, 36.299625, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T2 +(@GUID+69, 180815, 1, 0, 0, 1, 1, 1590.8533, -4155.339, 36.299156, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T3 +(@GUID+70, 180816, 1, 0, 0, 1, 1, 1590.8516, -4155.341, 36.299488, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL), -- T4 +(@GUID+71, 180817, 1, 0, 0, 1, 1, 1590.8517, -4155.3438, 36.299927, 3.7001047, 0, 0, -0.9612608, 0.2756405, 300, 0, 1, '', 61582, NULL); -- T5 + +-- Old spawns +DELETE FROM `gameobject` WHERE `guid` IN (29294, 29299, 29300, 29301) AND `id` IN (180598, 180679, 180680, 180681); diff --git a/data/sql/updates/db_world/2025_08_24_00.sql b/data/sql/updates/db_world/2025_08_24_00.sql new file mode 100644 index 000000000..0f3d678d9 --- /dev/null +++ b/data/sql/updates/db_world/2025_08_24_00.sql @@ -0,0 +1,3 @@ +-- DB update 2025_08_23_02 -> 2025_08_24_00 +-- +UPDATE `smart_scripts` SET `event_type` = 61 WHERE `entryorguid` = 18945 AND `source_type` = 0 AND `id` = 4; diff --git a/data/sql/updates/db_world/2025_08_25_00.sql b/data/sql/updates/db_world/2025_08_25_00.sql new file mode 100644 index 000000000..c5793e675 --- /dev/null +++ b/data/sql/updates/db_world/2025_08_25_00.sql @@ -0,0 +1,5 @@ +-- DB update 2025_08_24_00 -> 2025_08_25_00 +-- +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 4) AND (`SourceGroup` = 193997) AND (`SourceEntry` = 44725) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 5) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 1119) AND (`ConditionValue2` = 16) AND (`ConditionValue3` = 0); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(4, 26782, 44725, 0, 0, 5, 0, 1119, 240, 0, 0, 0, 0, '', 'Everfrost Chip requires Sons of Hodir friendly'); diff --git a/data/sql/updates/db_world/2025_08_25_01.sql b/data/sql/updates/db_world/2025_08_25_01.sql new file mode 100644 index 000000000..196057350 --- /dev/null +++ b/data/sql/updates/db_world/2025_08_25_01.sql @@ -0,0 +1,60 @@ +-- DB update 2025_08_25_00 -> 2025_08_25_01 +-- set dark portal creatures active +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (18944, 18946, 18948, 18949, 18950, 18965, 18966, 18969, 18970, 18971, 18972, 18986, -68744, -68745, -74081, -74082)) AND (`source_type` = 0) AND (`event_type` IN (11, 36)) AND (`id` IN (42, 43)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +-- 18944 Fel Soldier +(18944, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fel Soldier - On Respawn - Set Active On'), +(18944, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Fel Soldier - On Corpse Removed - Set Active On'), +-- 18945 Pit Commander, already set active +-- 18946 Infernal Siegebreaker +(18946, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Siegebreaker - On Respawn - Set Active On'), +(18946, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Siegebreaker - On Corpse Removed - Set Active On'), +-- 18948 Stormwind Soldier +(18948, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Stormwind Soldier - On Respawn - Set Active On'), +(18948, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Stormwind Soldier - On Corpse Removed - Set Active On'), +-- 18949 Stormwind Mage +(18949, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Stormwind Mage - On Respawn - Set Active On'), +(18949, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Stormwind Mage - On Corpse Removed - Set Active On'), +-- 18950 Orgrimmar Grunt +(18950, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Orgrimmar Grunt - On Respawn - Set Active On'), +(18950, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Orgrimmar Grunt - On Corpse Removed - Set Active On'), +-- 18965 Darnassian Archer +(18965, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Archer - On Respawn - Set Active On'), +(18965, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Archer - On Corpse Removed - Set Active On'), +-- 18966 Justinius the Harbinger +(18966, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Justinius the Harbinger - On Respawn - Set Active On'), +(18966, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Justinius the Harbinger - On Corpse Removed - Set Active On'), +-- 18969 Melgromm Highmountain +(18969, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Melgromm Highmountain - On Respawn - Set Active On'), +(18969, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Melgromm Highmountain - On Corpse Removed - Set Active On'), +-- 18970 Darkspear Axe Thrower +(18970, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darkspear Axe Thrower - On Respawn - Set Active On'), +(18970, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darkspear Axe Thrower - On Corpse Removed - Set Active On'), +-- 18971 Undercity Mage +(18971, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Undercity Mage - On Respawn - Set Active On'), +(18971, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Undercity Mage - On Corpse Removed - Set Active On'), +-- 18972 Orgrimmar Shaman +(18972, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Orgrimmar Shaman - On Respawn - Set Active On'), +(18972, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Orgrimmar Shaman - On Corpse Removed - Set Active On'), +-- 18986 Ironforge Paladin +(18986, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ironforge Paladin - On Respawn - Set Active On'), +(18986, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ironforge Paladin - On Corpse Removed - Set Active On'), +-- 19005 Wrath Master, GUID SAI -68311, -68312, -68313, -68314, already set active +-- 19215 Infernal Relay (Hellfire) +(-68744, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Relay (Hellfire) - On Respawn - Set Active On'), +(-68744, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Relay (Hellfire) - On Corpse Removed - Set Active On'), +(-68745, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Relay (Hellfire) - On Respawn - Set Active On'), +(-68745, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Relay (Hellfire) - On Corpse Removed - Set Active On'), +-- 21075 Infernal Target (Hyjal) +(-74081, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Target (Hyjal) - On Respawn - Set Active On'), +(-74081, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Target (Hyjal)- On Corpse Removed - Set Active On'), +(-74082, 0, 42, 0, 11, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Target (Hyjal) - On Respawn - Set Active On'), +(-74082, 0, 43, 0, 36, 0, 100, 512, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Infernal Target (Hyjal) - On Corpse Removed - Set Active On'); + +-- cleanup +-- Infernal Relay (Hellfire) used to set nearby 19005 Wrath Master active +DELETE FROM `smart_scripts` WHERE (`entryorguid` = -68744) AND (`source_type` = 0) AND (`id` IN (10)); +UPDATE `smart_scripts` SET `link` = 0 WHERE (`entryorguid` = -68744) AND (`source_type` = 0) AND (`id` IN (9)); + +-- update spawn comment for GUID SAI +UPDATE `creature` SET `Comment` = 'GUID SAI, SAI Target' WHERE (`id1` = 19215) AND (`guid` = 68745); diff --git a/data/sql/updates/db_world/2025_08_25_02.sql b/data/sql/updates/db_world/2025_08_25_02.sql new file mode 100644 index 000000000..47a79017c --- /dev/null +++ b/data/sql/updates/db_world/2025_08_25_02.sql @@ -0,0 +1,6 @@ +-- DB update 2025_08_25_01 -> 2025_08_25_02 +-- fix dark portal creatures calling for help on aggro +-- 18948 Stormwind Soldier +UPDATE `smart_scripts` SET `event_type` = 4 WHERE (`entryorguid` = 18948) AND (`source_type` = 0) AND (`id` IN (7)); +-- 18950 Orgrimmar Grunt +UPDATE `smart_scripts` SET `event_type` = 4 WHERE (`entryorguid` = 18950) AND (`source_type` = 0) AND (`id` IN (7)); diff --git a/data/sql/updates/db_world/2025_08_27_00.sql b/data/sql/updates/db_world/2025_08_27_00.sql new file mode 100644 index 000000000..13cac6c78 --- /dev/null +++ b/data/sql/updates/db_world/2025_08_27_00.sql @@ -0,0 +1,6 @@ +-- DB update 2025_08_25_02 -> 2025_08_27_00 +UPDATE `item_template` SET `armor` = 1983, `MaxDurability` = 165 WHERE `entry` = 40440; +UPDATE `item_template` SET `armor` = 1239, `MaxDurability` = 55 WHERE `entry` = 40441; +UPDATE `item_template` SET `armor` = 1611, `MaxDurability` = 100 WHERE `entry` = 40442; +UPDATE `item_template` SET `armor` = 1735, `MaxDurability` = 120 WHERE `entry` = 40443; +UPDATE `item_template` SET `armor` = 1487, `MaxDurability` = 100 WHERE `entry` = 40444; diff --git a/data/sql/updates/db_world/2025_08_27_01.sql b/data/sql/updates/db_world/2025_08_27_01.sql new file mode 100644 index 000000000..eab3c1735 --- /dev/null +++ b/data/sql/updates/db_world/2025_08_27_01.sql @@ -0,0 +1,83 @@ +-- DB update 2025_08_27_00 -> 2025_08_27_01 +SET @SAY_APPROACH = 0, +@SAY_AGGRO = 1, +@SAY_SUMMON = 2, +@GUID = 12748; + +DELETE FROM `areatrigger_scripts` WHERE `entry` IN (5014, 5015); +INSERT INTO `areatrigger_scripts` (`entry`, `ScriptName`) VALUES +(5014, 'at_karazhan_mirkblood_approach'), +(5015, 'at_karazhan_mirkblood_entrance'); + +UPDATE `creature_template` SET `minlevel` = 73, `maxlevel` = 73, `speed_run` = 1.85714285714, `ScriptName` = 'boss_tenris_mirkblood' WHERE `entry` = 28194; +UPDATE `creature_template` SET `speed_walk` = 0.4, `speed_run` = 0.14285714285, `ScriptName` = 'npc_sanguine_spirit' WHERE `entry` = 28232; +UPDATE `creature_template` SET `unit_flags` = 33554432, `AIName` = 'SmartAI' WHERE `entry` = 28485; +UPDATE `creature_template` SET `unit_flags` = 33555200 WHERE `entry` = 28493; + +UPDATE `creature_model_info` SET `BoundingRadius` = 0.200000002980232238, `CombatReach` = 0.400000005960464477 WHERE `DisplayID` = 25296; +UPDATE `creature_model_info` SET `BoundingRadius` = 0.465000003576278686, `CombatReach` = 1.5 WHERE `DisplayID` = 25541; + +DELETE FROM `creature_text` WHERE `CreatureID` = 28194; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(28194, @SAY_APPROACH, 0, 'I smell... $r. Delicious!', 14, 0, 100, 0, 0, 0, 27780, 0, 'Prince Tenris Mirkblood - SAY_APPROACH'), +(28194, @SAY_AGGRO, 0, 'I shall consume you!', 14, 0, 100, 0, 0, 0, 27781, 0, 'Prince Tenris Mirkblood - SAY_AGGRO'), +(28194, @SAY_SUMMON, 0, 'Drink, mortals! Taste my blood! Taste your death!', 12, 0, 100, 0, 0, 0, 27712, 0, 'Prince Tenris Mirkblood - SAY_SUMMON'); + +UPDATE `gameobject_template` SET `ScriptName` = 'go_blood_drenched_door' WHERE `entry` = 181032; + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (50883, 50925, 51013); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(50883, 'spell_mirkblood_blood_mirror_target_picker'), +(50925, 'spell_mirkblood_dash_gash_return_to_tank_pre_spell'), +(51013, 'spell_mirkblood_exsanguinate'); + +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` = -50845 AND `spell_effect` = -50844; +INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES +(-50845, -50844, 0, 'Tenris Mirkblood Blood Mirror'); + +DELETE FROM `creature_template_addon` WHERE `entry` IN (28232, 28485, 28493); +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES +(28232, 0, 0, 0, 0, 0, 0, '51282'), +(28485, 0, 0, 0, 0, 0, 0, '30987'), +(28493, 0, 0, 0, 0, 383, 0, ''); + +DELETE FROM `creature_template_movement` WHERE `CreatureId` IN (28485, 28493); +INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`, `Chase`, `Random`, `InteractionPauseTimer`) VALUES +(28485, 0, 0, 1, 0, 0, 0, NULL), +(28493, 0, 0, 1, 0, 0, 0, NULL); + +DELETE FROM `creature` WHERE `guid` BETWEEN @GUID+0 AND @GUID+9 AND `id1` IN (28485, 28493); +INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(@GUID+0, 28485, 0, 0, 532, 0, 0, 1, 1, 0, -11087.619, -1996.4193, 82.59072, 0.453785598278045654, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+1, 28485, 0, 0, 532, 0, 0, 1, 1, 0, -11104.703, -1973.5052, 82.73294, 0.05235987901687622, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+2, 28485, 0, 0, 532, 0, 0, 1, 1, 0, -11084.556, -1981.4388, 82.4658, 0.575958669185638427, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+3, 28485, 0, 0, 532, 0, 0, 1, 1, 0, -11091.643, -1961.8134, 82.77006, 0.104719758033752441, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+4, 28485, 0, 0, 532, 0, 0, 1, 1, 0, -11097.971, -1982.734, 82.39082, 0.418879032135009765, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+5, 28493, 0, 0, 532, 0, 0, 1, 1, 0, -11097.721, -1982.62, 77.43985, 5.113814830780029296, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+6, 28493, 0, 0, 532, 0, 0, 1, 1, 0, -11104.523, -1973.4592, 78.07421, 1.396263360977172851, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+7, 28493, 0, 0, 532, 0, 0, 1, 1, 0, -11084.696, -1981.4202, 77.87848, 4.904375076293945312, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+8, 28493, 0, 0, 532, 0, 0, 1, 1, 0, -11091.594, -1962.1276, 78.054115, 2.146754980087280273, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL), +(@GUID+9, 28493, 0, 0, 532, 0, 0, 1, 1, 0, -11087.617, -1996.2291, 77.72322, 0.436332315206527709, 300, 0, 0, 4050, 0, 0, 0, 0, 0, '', 49345, 2, NULL); + +DELETE FROM `game_event_creature` WHERE `eventEntry` = 120 AND `guid` BETWEEN @GUID+0 AND @GUID+9; +INSERT INTO `game_event_creature` (`eventEntry`, `guid`) VALUES +(120, @GUID+0), +(120, @GUID+1), +(120, @GUID+2), +(120, @GUID+3), +(120, @GUID+4), +(120, @GUID+5), +(120, @GUID+6), +(120, @GUID+7), +(120, @GUID+8), +(120, @GUID+9); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28485) AND (`source_type` = 0) AND (`id` IN (0)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(28485, 0, 0, 0, 37, 0, 100, 0, 0, 0, 0, 0, 0, 11, 51773, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blood Vat Bunny - On Initialize - Cast \'Scourge Invasion Blood Vat Bunny\''); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` = 51773 AND `ConditionTypeOrReference` = 31 AND `ConditionValue2` = 28485; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 51773, 0, 0, 31, 0, 3, 28485, 0, 0, 0, 0, '', 'Target must be unit Blood Vat Bunny'); + +UPDATE `spell_dbc` SET `Effect_1` = 28, `EffectMiscValue_1` = 28232, `EffectMiscValueB_1` = 64 WHERE `ID` = 50996; diff --git a/src/server/apps/authserver/Main.cpp b/src/server/apps/authserver/Main.cpp index e9ed0119f..b5fbb319a 100644 --- a/src/server/apps/authserver/Main.cpp +++ b/src/server/apps/authserver/Main.cpp @@ -29,6 +29,7 @@ #include "Config.h" #include "DatabaseEnv.h" #include "DatabaseLoader.h" +#include "GitRevision.h" #include "IPLocation.h" #include "IoContext.h" #include "Log.h" @@ -75,7 +76,7 @@ int main(int argc, char** argv) auto vm = GetConsoleArguments(argc, argv, configFile); // exit if help or version is enabled - if (vm.count("help")) + if (vm.count("help") || vm.count("version")) return 0; // Add file and args in config @@ -292,13 +293,11 @@ variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile) } if (variablesMap.count("help")) - { std::cout << all << "\n"; - } + else if (variablesMap.count("version")) + std::cout << GitRevision::GetFullVersion() << "\n"; else if (variablesMap.count("dry-run")) - { sConfigMgr->setDryRun(true); - } return variablesMap; } diff --git a/src/server/apps/worldserver/Main.cpp b/src/server/apps/worldserver/Main.cpp index d259f0220..31fa1b16e 100644 --- a/src/server/apps/worldserver/Main.cpp +++ b/src/server/apps/worldserver/Main.cpp @@ -127,7 +127,7 @@ int main(int argc, char** argv) auto vm = GetConsoleArguments(argc, argv, configFile, configService); // exit if help or version is enabled - if (vm.count("help")) + if (vm.count("help") || vm.count("version")) return 0; #if AC_PLATFORM == AC_PLATFORM_WINDOWS @@ -744,13 +744,11 @@ variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, [ } if (vm.count("help")) - { std::cout << all << "\n"; - } + else if (vm.count("version")) + std::cout << GitRevision::GetFullVersion() << "\n"; else if (vm.count("dry-run")) - { sConfigMgr->setDryRun(true); - } return vm; } diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index db0936a04..634df5262 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -657,7 +657,7 @@ Appender.Console=1,4,0,"1 9 3 6 5 8" Appender.Server=2,5,0,Server.log,w Appender.Playerbots=2,5,0,Playerbots.log,w # Appender.GM=2,5,15,gm_%s.log -Appender.Errors=2,5,0,Errors.log,w +Appender.Errors=2,2,0,Errors.log,w # Appender.DB=3,5,0 # Logger config values: Given a logger "name" @@ -686,6 +686,7 @@ Logger.mmaps=4,Server Logger.scripts.hotswap=4,Console Server Logger.server=4,Console Server Logger.sql.sql=2,Console Errors +Logger.sql.updates=4,Console Server Errors Logger.sql=4,Console Server Logger.time.update=4,Console Server Logger.module=4,Console Server @@ -785,7 +786,6 @@ Logger.playerbots=5,Console Playerbots #Logger.spells=4,Console Server #Logger.sql.dev=4,Console Server #Logger.sql.driver=4,Console Server -#Logger.sql.updates=4,Console Server #Logger.vehicles=4,Console Server #Logger.warden=4,Console Server #Logger.weather=4,Console Server @@ -3143,6 +3143,16 @@ LeaveGroupOnLogout.Enabled = 0 Group.Raid.LevelRestriction = 10 +# +# Group.RandomRollMaximum +# +# The maximum value for use with the client '/roll' command. +# Blizzlike and maximum value is 1000000. (Based on Classic and 3.3.5a client testing respectively) +# Default: 1000000 +# + +Group.RandomRollMaximum = 1000000 + # ################################################################################################### diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 80ebac719..5f304eac0 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -607,7 +607,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_INS_PROFANITY_PLAYER_NAME, "INSERT IGNORE INTO profanity_name (name) VALUES (?)", CONNECTION_ASYNC); // Character settings - PrepareStatement(CHAR_SEL_CHAR_SETTINGS, "SELECT source, data FROM character_settings WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CHAR_SETTINGS, "SELECT source, data FROM character_settings WHERE guid = ?", CONNECTION_BOTH); PrepareStatement(CHAR_REP_CHAR_SETTINGS, "REPLACE INTO character_settings (guid, source, data) VALUES (?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_SETTINGS, "DELETE FROM character_settings WHERE guid = ?", CONNECTION_ASYNC); diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index d48cf2681..4c2b252e2 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -72,6 +72,8 @@ SmartAI::SmartAI(Creature* c) : CreatureAI(c) mcanSpawn = true; + _chaseOnInterrupt = false; + // Xinef: Vehicle conditions m_ConditionsTimer = 0; if (me->GetVehicleKit()) diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index ede658a47..1cc940df4 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -212,6 +212,9 @@ public: // Xinef void SetWPPauseTimer(uint32 time) { mWPPauseTimer = time; } + void SetChaseOnInterrupt(bool apply) { _chaseOnInterrupt = apply; } + [[nodiscard]] bool CanChaseOnInterrupt() const { return _chaseOnInterrupt; } + private: bool mIsCharmed; uint32 mFollowCreditType; @@ -257,6 +260,8 @@ private: void CheckConditions(const uint32 diff); ConditionList conditions; uint32 m_ConditionsTimer; + + bool _chaseOnInterrupt; }; class SmartGameObjectAI : public GameObjectAI diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 24a3d6901..e0a6f4fb8 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -742,6 +742,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (e.action.cast.castFlags & SMARTCAST_COMBAT_MOVE) { + CAST_AI(SmartAI, me->AI())->SetChaseOnInterrupt(true); + if (!me->isMoving()) // Don't try to reposition while we are moving { // If cast flag SMARTCAST_COMBAT_MOVE is set combat movement will not be allowed unless target is outside spell range, out of mana, or LOS. @@ -893,7 +895,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u go->SetLootState(GO_READY); } - go->UseDoorOrButton(0, !!e.action.activateObject.alternative, unit); + go->UseDoorOrButton(0, e.action.activateObject.alternative, unit); LOG_DEBUG("sql.sql", "SmartScript::ProcessAction:: SMART_ACTION_ACTIVATE_GOBJECT. Gameobject {} activated", go->GetGUID().ToString()); } } @@ -1483,14 +1485,14 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { for (WorldObject* target : targets) if (IsUnit(target)) - target->ToUnit()->SetVisible(!!e.action.visibility.state); + target->ToUnit()->SetVisible(e.action.visibility.state); break; } case SMART_ACTION_SET_ACTIVE: { for (WorldObject* target : targets) - target->setActive(!!e.action.setActive.state); + target->setActive(e.action.setActive.state); break; } case SMART_ACTION_ATTACK_START: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 0040e0bd3..9185f77ac 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -202,10 +202,29 @@ void SmartAIMgr::LoadSmartAIFromDB() } else { - if (!sObjectMgr->GetCreatureData(uint32(std::abs(temp.entryOrGuid)))) + switch (source_type) { - LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid ({}) does not exist, skipped loading.", uint32(std::abs(temp.entryOrGuid))); - continue; + case SMART_SCRIPT_TYPE_CREATURE: + { + if (!sObjectMgr->GetCreatureData(uint32(std::abs(temp.entryOrGuid)))) + { + LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid ({}) does not exist, skipped loading.", uint32(std::abs(temp.entryOrGuid))); + continue; + } + break; + } + case SMART_SCRIPT_TYPE_GAMEOBJECT: + { + if (!sObjectMgr->GetGameObjectData(uint32(std::abs(temp.entryOrGuid)))) + { + LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: GameObject guid ({}) does not exist, skipped loading.", uint32(temp.entryOrGuid)); + continue; + } + break; + } + default: + LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: not yet implemented source_type {}", (uint32)source_type); + continue; } } diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 736fd46e1..dcc1b7662 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -488,7 +488,7 @@ void AuctionHouseObject::AddAuction(AuctionEntry* auction) bool AuctionHouseObject::RemoveAuction(AuctionEntry* auction) { - bool wasInMap = !!_auctionsMap.erase(auction->Id); + bool wasInMap = _auctionsMap.erase(auction->Id); sAuctionMgr->GetAuctionHouseSearcher()->RemoveAuction(auction); sScriptMgr->OnAuctionRemove(this, auction); diff --git a/src/server/game/Chat/HyperlinkTags.cpp b/src/server/game/Chat/HyperlinkTags.cpp index 342ba3035..2cb36b698 100644 --- a/src/server/game/Chat/HyperlinkTags.cpp +++ b/src/server/game/Chat/HyperlinkTags.cpp @@ -206,7 +206,7 @@ bool Acore::Hyperlinks::LinkTags::spell::StoreTo(SpellInfo const*& val, std::str if (!(t.TryConsumeTo(spellId) && t.IsEmpty())) return false; - return !!(val = sSpellMgr->GetSpellInfo(spellId)); + return (val = sSpellMgr->GetSpellInfo(spellId)); } bool Acore::Hyperlinks::LinkTags::talent::StoreTo(TalentLinkData& val, std::string_view text) diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 93bdc0c8a..09edfab28 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -68,7 +68,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) { // don't allow 0 items (it's checked during table load) ASSERT(ConditionValue2); - bool checkBank = !!ConditionValue3; + bool checkBank = ConditionValue3; condMeets = player->HasItemCount(ConditionValue1, ConditionValue2, checkBank); } } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index dbaea048f..cbd823141 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1987,8 +1987,6 @@ void Creature::setDeathState(DeathState state, bool despawn) Dismount(); // if creature is mounted on a virtual mount, remove it at death - setActive(false); - if (HasSearchedAssistance()) { SetNoSearchAssistance(false); @@ -3904,7 +3902,7 @@ bool Creature::IsUpdateNeeded() if (IsInCombat()) return true; - if (IsVisibilityOverridden()) + if (!GetObjectVisibilityContainer().GetVisiblePlayersMap().empty()) return true; if (ToTempSummon()) diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h index 2cb6e9ae8..54b01c08c 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.h +++ b/src/server/game/Entities/Creature/CreatureGroups.h @@ -67,7 +67,7 @@ struct FormationInfo uint32 point_1; uint32 point_2; - bool HasGroupFlag(uint16 flag) const { return !!(groupAI & flag); } + bool HasGroupFlag(uint16 flag) const { return (groupAI & flag); } }; typedef std::unordered_map CreatureGroupInfoType; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 827dc38dd..1fa5a4177 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -3086,7 +3086,7 @@ bool GameObject::IsUpdateNeeded() if (GetMap()->isCellMarked(GetCurrentCell().GetCellCoord().GetId())) return true; - if (IsVisibilityOverridden()) + if (!GetObjectVisibilityContainer().GetVisiblePlayersMap().empty()) return true; if (IsTransport()) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 37605de21..1b8ccd047 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -156,8 +156,8 @@ public: void SaveToDB(bool saveAddon = false); void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask, bool saveAddon = false); - bool LoadFromDB(ObjectGuid::LowType guid, Map* map) { return LoadGameObjectFromDB(guid, map, false); } - bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true); + virtual bool LoadFromDB(ObjectGuid::LowType guid, Map* map) { return LoadGameObjectFromDB(guid, map, false); } + virtual bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true); void DeleteFromDB(); void SetOwnerGUID(ObjectGuid owner) diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index a9fcd7199..3081013be 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1696,7 +1696,7 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo if (this == obj) return true; - if (obj->IsNeverVisible() || CanNeverSee(obj)) + if (CanNeverSee(obj)) return false; if (obj->IsAlwaysVisibleFor(this) || CanAlwaysSee(obj)) @@ -1840,6 +1840,12 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo bool WorldObject::CanNeverSee(WorldObject const* obj) const { + if (!IsInWorld()) + return true; + + if (obj->IsNeverVisible()) + return true; + if (IsCreature() && obj->IsCreature()) return GetMap() != obj->GetMap() || (!InSamePhase(obj) && ToUnit()->GetVehicleBase() != obj && this != obj->ToUnit()->GetVehicleBase()); return GetMap() != obj->GetMap() || !InSamePhase(obj); diff --git a/src/server/game/Entities/Object/ObjectVisibilityContainer.cpp b/src/server/game/Entities/Object/ObjectVisibilityContainer.cpp index 9831adf5a..358626180 100644 --- a/src/server/game/Entities/Object/ObjectVisibilityContainer.cpp +++ b/src/server/game/Entities/Object/ObjectVisibilityContainer.cpp @@ -66,6 +66,10 @@ void ObjectVisibilityContainer::LinkWorldObjectVisibility(WorldObject* worldObje if (worldObject == _selfObject) return; + // Transports are special and should not be added to our visibility map + if (worldObject->IsGameObject() && worldObject->ToGameObject()->IsTransport()) + return; + // Only players can link visibility if (!_visibleWorldObjectsMap) return; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 21b2a8e02..1969d4c67 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4552,6 +4552,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) // update visibility UpdateObjectVisibility(); + // recast lost by death auras of any items held in the inventory + CastAllObtainSpells(); + sScriptMgr->OnPlayerResurrect(this, restore_percent, applySickness); if (!applySickness) @@ -6019,6 +6022,7 @@ void Player::RewardReputation(Unit* victim) if (Rep->RepFaction1 && (!Rep->TeamDependent || teamId == TEAM_ALLIANCE)) { float donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), static_cast(Rep->RepValue1), ChampioningFaction ? ChampioningFaction : Rep->RepFaction1); + sScriptMgr->OnPlayerGiveReputation(this, Rep->RepFaction1, donerep1, REPUTATION_SOURCE_KILL); FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction1); if (factionEntry1) @@ -6030,6 +6034,7 @@ void Player::RewardReputation(Unit* victim) if (Rep->RepFaction2 && (!Rep->TeamDependent || teamId == TEAM_HORDE)) { float donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), static_cast(Rep->RepValue2), ChampioningFaction ? ChampioningFaction : Rep->RepFaction2); + sScriptMgr->OnPlayerGiveReputation(this, Rep->RepFaction2, donerep2, REPUTATION_SOURCE_KILL); FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction2); if (factionEntry2) @@ -6069,22 +6074,27 @@ void Player::RewardReputation(Quest const* quest) if (quest->IsDaily()) { rep = CalculateReputationGain(REPUTATION_SOURCE_DAILY_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false); + sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_DAILY_QUEST); } else if (quest->IsWeekly()) { rep = CalculateReputationGain(REPUTATION_SOURCE_WEEKLY_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false); + sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_WEEKLY_QUEST); } else if (quest->IsMonthly()) { rep = CalculateReputationGain(REPUTATION_SOURCE_MONTHLY_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false); + sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_MONTHLY_QUEST); } else if (quest->IsRepeatable()) { rep = CalculateReputationGain(REPUTATION_SOURCE_REPEATABLE_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false); + sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_REPEATABLE_QUEST); } else { rep = CalculateReputationGain(REPUTATION_SOURCE_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false); + sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_QUEST); } if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(quest->RewardFactionId[i])) @@ -7028,6 +7038,46 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt UpdateDamagePhysical(WeaponAttackType(attType)); } +void Player::CastAllObtainSpells() +{ + for (uint8 slot = INVENTORY_SLOT_ITEM_START; slot < INVENTORY_SLOT_ITEM_END; ++slot) + if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) + ApplyItemObtainSpells(item, true); + + for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) + { + Bag* bag = GetBagByPos(i); + if (!bag) + continue; + + for (uint32 slot = 0; slot < bag->GetBagSize(); ++slot) + if (Item* item = bag->GetItemByPos(slot)) + ApplyItemObtainSpells(item, true); + } +} + +void Player::ApplyItemObtainSpells(Item* item, bool apply) +{ + ItemTemplate const* itemTemplate = item->GetTemplate(); + for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) + { + if (itemTemplate->Spells[i].SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE) // On obtain trigger + continue; + + int32 const spellId = itemTemplate->Spells[i].SpellId; + if (spellId <= 0) + continue; + + if (apply) + { + if (!HasAura(spellId)) + CastSpell(this, spellId, true, item); + } + else + RemoveAurasDueToSpell(spellId); + } +} + SpellSchoolMask Player::GetMeleeDamageSchoolMask(WeaponAttackType attackType /*= BASE_ATTACK*/, uint8 damageIndex /*= 0*/) const { if (Item const* weapon = GetWeaponForAttack(attackType, true)) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 933f30148..8ec139381 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -235,17 +235,6 @@ enum ActionButtonType ACTION_BUTTON_ITEM = 0x80 }; -enum ReputationSource -{ - REPUTATION_SOURCE_KILL, - REPUTATION_SOURCE_QUEST, - REPUTATION_SOURCE_DAILY_QUEST, - REPUTATION_SOURCE_WEEKLY_QUEST, - REPUTATION_SOURCE_MONTHLY_QUEST, - REPUTATION_SOURCE_REPEATABLE_QUEST, - REPUTATION_SOURCE_SPELL -}; - enum QuestSound { QUEST_SOUND_FAILURE = 847 @@ -1682,7 +1671,7 @@ public: bool RemoveMItem(ObjectGuid::LowType itemLowGuid) { - return !!mMitems.erase(itemLowGuid); + return mMitems.erase(itemLowGuid); } void PetSpellInitialize(); @@ -2208,6 +2197,9 @@ public: void ResetAllPowers(); + void CastAllObtainSpells(); + void ApplyItemObtainSpells(Item* item, bool apply); + SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK, uint8 damageIndex = 0) const override; void _ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply); @@ -2632,8 +2624,8 @@ public: std::string GetPlayerName(); // Settings - [[nodiscard]] PlayerSetting GetPlayerSetting(std::string const& source, uint8 index); - void UpdatePlayerSetting(std::string const& source, uint8 index, uint32 value); + [[nodiscard]] PlayerSetting GetPlayerSetting(std::string const& source, uint32 index); + void UpdatePlayerSetting(std::string const& source, uint32 index, uint32 value); void SendSystemMessage(std::string_view msg, bool escapeCharacters = false); diff --git a/src/server/game/Entities/Player/PlayerSettings.cpp b/src/server/game/Entities/Player/PlayerSettings.cpp index dba4afaa5..1fd4aae3a 100644 --- a/src/server/game/Entities/Player/PlayerSettings.cpp +++ b/src/server/game/Entities/Player/PlayerSettings.cpp @@ -18,11 +18,95 @@ #include "Player.h" #include "StringConvert.h" #include "Tokenize.h" +#include "CharacterDatabase.h" /*********************************************************/ /*** PLAYER SETTINGS SYSTEM ***/ /*********************************************************/ +namespace PlayerSettingsStore +{ + // Common helper: parse space-separated data string into PlayerSettingVector + PlayerSettingVector ParseSettingsData(std::string const& data) + { + PlayerSettingVector result; + std::vector tokens = Acore::Tokenize(data, ' ', false); + result.reserve(tokens.size()); + for (auto const& token : tokens) + { + if (token.empty()) + continue; + if (auto parsed = Acore::StringTo(token)) + result.emplace_back(*parsed); + } + return result; + } + + // Common helper: serialize PlayerSettingVector to space-separated string + std::string SerializeSettingsData(PlayerSettingVector const& settings) + { + if (settings.empty()) + return ""; + + std::ostringstream data; + data << settings[0].value; + for (size_t i = 1; i < settings.size(); ++i) + data << ' ' << settings[i].value; + return data.str(); + } + + // helper: load a single source row for a player and parse to vector + static PlayerSettingVector LoadPlayerSettings(uint32 playerLowGuid, std::string const& source) + { + PlayerSettingVector result; + + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_SETTINGS); + stmt->SetData(0, playerLowGuid); + PreparedQueryResult dbRes = CharacterDatabase.Query(stmt); + if (!dbRes) + return result; + + do + { + Field* fields = dbRes->Fetch(); + std::string rowSource = fields[0].Get(); + if (rowSource != source) + continue; + + std::string data = fields[1].Get(); + return ParseSettingsData(data); + } while (dbRes->NextRow()); + + return result; + } + + void UpdateSetting(uint32 playerLowGuid, std::string const& source, uint32 index, uint32 value) + { + if (!sWorld->getBoolConfig(CONFIG_PLAYER_SETTINGS_ENABLED)) + return; + + PlayerSettingVector settings = LoadPlayerSettings(playerLowGuid, source); + size_t const requiredSize = static_cast(index) + 1; + if (settings.size() < requiredSize) + settings.resize(requiredSize); // zero-initialized PlayerSetting::value + + settings[index].value = value; + + CharacterDatabasePreparedStatement* stmt = PlayerSettingsStore::PrepareReplaceStatement(playerLowGuid, source, settings); + CharacterDatabase.Execute(stmt); + } +} + +// Implementation of PrepareReplaceStatement +CharacterDatabasePreparedStatement* PlayerSettingsStore::PrepareReplaceStatement(uint32 playerLowGuid, std::string const& source, PlayerSettingVector const& settings) +{ + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHAR_SETTINGS); + stmt->SetData(0, playerLowGuid); + stmt->SetData(1, source); + stmt->SetData(2, SerializeSettingsData(settings)); + return stmt; +} + void Player::_LoadCharacterSettings(PreparedQueryResult result) { m_charSettingsMap.clear(); @@ -39,27 +123,13 @@ void Player::_LoadCharacterSettings(PreparedQueryResult result) std::string source = fields[0].Get(); std::string data = fields[1].Get(); - std::vector tokens = Acore::Tokenize(data, ' ', false); - - PlayerSettingVector settings; - settings.reserve(tokens.size()); // reserve capacity but don't resize - - for (auto const& token : tokens) - { - if (token.empty()) - continue; - - // Try to parse the value safely - if (auto parsed = Acore::StringTo(token)) - settings.emplace_back(*parsed); - } - + PlayerSettingVector settings = PlayerSettingsStore::ParseSettingsData(data); m_charSettingsMap.emplace(std::move(source), std::move(settings)); } while (result->NextRow()); } -PlayerSetting Player::GetPlayerSetting(std::string const& source, uint8 index) +PlayerSetting Player::GetPlayerSetting(std::string const& source, uint32 index) { auto it = m_charSettingsMap.find(source); if (it == m_charSettingsMap.end() || static_cast(index) >= it->second.size()) @@ -81,21 +151,12 @@ void Player::_SavePlayerSettings(CharacterDatabaseTransaction trans) if (settings.empty()) continue; - std::ostringstream data; - data << settings[0].value; - - for (size_t i = 1; i < settings.size(); ++i) - data << ' ' << settings[i].value; - - CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHAR_SETTINGS); - stmt->SetData(0, GetGUID().GetCounter()); - stmt->SetData(1, source); - stmt->SetData(2, data.str()); + CharacterDatabasePreparedStatement* stmt = PlayerSettingsStore::PrepareReplaceStatement(GetGUID().GetCounter(), source, settings); trans->Append(stmt); } } -void Player::UpdatePlayerSetting(std::string const& source, uint8 index, uint32 value) +void Player::UpdatePlayerSetting(std::string const& source, uint32 index, uint32 value) { auto it = m_charSettingsMap.find(source); size_t const requiredSize = static_cast(index) + 1; diff --git a/src/server/game/Entities/Player/PlayerSettings.h b/src/server/game/Entities/Player/PlayerSettings.h index 027062e3c..4e0c96135 100644 --- a/src/server/game/Entities/Player/PlayerSettings.h +++ b/src/server/game/Entities/Player/PlayerSettings.h @@ -17,6 +17,7 @@ #ifndef _PLAYER_SETTINGS_H #define _PLAYER_SETTINGS_H +#include "DatabaseEnvFwd.h" class Player; @@ -51,4 +52,18 @@ struct PlayerSetting typedef std::vector PlayerSettingVector; typedef std::map PlayerSettingMap; +// Standalone API: update a player's setting directly on DB by GUID (low part) without requiring a Player instance +namespace PlayerSettingsStore +{ + // Update a single setting value for any player by GUID (works for online or offline players). + // This reads the existing "source" row from character_settings, adjusts the index, and REPLACE's it back. + void UpdateSetting(uint32 playerLowGuid, std::string const& source, uint32 index, uint32 value); + + // Common helpers for parsing and serializing settings data + PlayerSettingVector ParseSettingsData(std::string const& data); + std::string SerializeSettingsData(PlayerSettingVector const& settings); + // Prepare a REPLACE statement populated with given settings data. Caller may execute or append to a transaction. + CharacterDatabasePreparedStatement* PrepareReplaceStatement(uint32 playerLowGuid, std::string const& source, PlayerSettingVector const& settings); +} + #endif diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index 01595faa5..4836811e2 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -2577,8 +2577,6 @@ Item* Player::StoreItem(ItemPosCountVec const& dest, Item* pItem, bool update) return nullptr; Item* lastItem = pItem; - ItemTemplate const* proto = pItem->GetTemplate(); - for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end();) { uint16 pos = itr->pos; @@ -2595,13 +2593,6 @@ Item* Player::StoreItem(ItemPosCountVec const& dest, Item* pItem, bool update) lastItem = _StoreItem(pos, pItem, count, true, update); } - // cast after item storing - some checks in checkcast requires item to be present!! - if (lastItem) - for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) - if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger - if (!HasAura(proto->Spells[i].SpellId)) - CastSpell(this, proto->Spells[i].SpellId, true, lastItem); - return lastItem; } @@ -2664,6 +2655,9 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool AddEnchantmentDurations(pItem); AddItemDurations(pItem); + if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)) + ApplyItemObtainSpells(pItem, true); + return pItem; } else @@ -2700,6 +2694,9 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool pItem2->SetState(ITEM_CHANGED, this); + if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)) + ApplyItemObtainSpells(pItem2, true); + return pItem2; } } @@ -3046,10 +3043,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update) pItem->ClearSoulboundTradeable(this); RemoveTradeableItem(pItem); - ItemTemplate const* proto = pItem->GetTemplate(); - for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) - if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger - RemoveAurasDueToSpell(proto->Spells[i].SpellId); + ApplyItemObtainSpells(pItem, false); ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount()); @@ -3102,8 +3096,9 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update) pBag->RemoveItem(slot, update); // Xinef: item is removed, remove loot from storage if any - if (proto->HasFlag(ITEM_FLAG_HAS_LOOT)) - sLootItemStorage->RemoveStoredLoot(pItem->GetGUID()); + if (ItemTemplate const* proto = pItem->GetTemplate()) + if (proto->HasFlag(ITEM_FLAG_HAS_LOOT)) + sLootItemStorage->RemoveStoredLoot(pItem->GetGUID()); if (IsInWorld() && update) { diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index bdd95a4f7..ace8b0726 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -1646,10 +1646,7 @@ template <> inline void UpdateVisibilityOf_helper(Player* player, GameObject* target, std::vector& /*v*/) { - // @HACK: This is to prevent objects like deeprun tram from disappearing - // when player moves far from its spawn point while riding it - if ((target->GetGOInfo()->type != GAMEOBJECT_TYPE_TRANSPORT)) - player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target); + player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target); } template <> diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 251cdb936..ee87af41d 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -607,12 +607,12 @@ void MotionTransport::DelayedTeleportTransport() } Map* newMap = sMapMgr->CreateBaseMap(newMapId); - GetMap()->RemoveFromMap(this, false); + GetMap()->RemoveFromMap(this, false); newMap->LoadGrid(x, y); // xinef: load before adding passengers to new map SetMap(newMap); Relocate(x, y, z, o); - GetMap()->AddToMap(this); + GetMap()->AddToMap(this); LoadStaticPassengers(); } @@ -690,6 +690,40 @@ StaticTransport::~StaticTransport() ASSERT(_passengers.empty()); } +bool StaticTransport::LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap) +{ + GameObjectData const* data = sObjectMgr->GetGameObjectData(spawnId); + + if (!data) + { + LOG_ERROR("sql.sql", "Gameobject (GUID: {}) not found in table `gameobject`, can't load. ", spawnId); + return false; + } + + uint32 entry = data->id; + //uint32 map_id = data->mapid; // already used before call + uint32 phaseMask = data->phaseMask; + float x = data->posX; + float y = data->posY; + float z = data->posZ; + float ang = data->orientation; + + uint32 animprogress = data->animprogress; + GOState go_state = data->go_state; + uint32 artKit = data->artKit; + + m_goData = data; + m_spawnId = spawnId; + + if (!Create(map->GenerateLowGuid(), entry, map, phaseMask, x, y, z, ang, data->rotation, animprogress, go_state, artKit)) + return false; + + if (addToMap && !GetMap()->AddToMap(this)) + return false; + + return true; +} + bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const& rotation, uint32 animprogress, GOState go_state, uint32 artKit) { ASSERT(map); @@ -794,7 +828,6 @@ bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* m LastUsedScriptID = GetGOInfo()->ScriptId; AIM_Initialize(); - this->setActive(true); return true; } @@ -929,7 +962,9 @@ void StaticTransport::UpdatePosition(float x, float y, float z, float o) if (!GetMap()->IsGridLoaded(x, y)) // pussywizard: should not happen, but just in case GetMap()->LoadGrid(x, y); - GetMap()->GameObjectRelocation(this, x, y, z, o); // this also relocates the model + Relocate(x, y, z, o); + UpdateModelPosition(); + UpdatePassengerPositions(); } diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index 005e9d789..9b50775af 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -38,6 +38,8 @@ public: virtual void RemovePassenger(WorldObject* passenger, bool withAll = false) = 0; PassengerSet const& GetPassengers() const { return _passengers; } + virtual void DelayedUpdate(uint32 /*diff*/) {} + uint32 GetPathProgress() const { return GetGOValue()->Transport.PathProgress; } void SetPathProgress(uint32 val) { m_goValue.Transport.PathProgress = val; } @@ -57,7 +59,7 @@ public: void BuildUpdate(UpdateDataMapType& data_map) override; void Update(uint32 diff) override; - void DelayedUpdate(uint32 diff); + void DelayedUpdate(uint32 diff) override; void UpdatePosition(float x, float y, float z, float o); void AddPassenger(WorldObject* passenger, bool withAll = false) override; @@ -115,6 +117,8 @@ public: StaticTransport(); ~StaticTransport() override; + bool LoadFromDB(ObjectGuid::LowType guid, Map* map) override { return LoadGameObjectFromDB(guid, map, false); } + bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true) override; bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const& rotation, uint32 animprogress, GOState go_state, uint32 artKit = 0) override; void CleanupsBeforeDelete(bool finalCleanup = true) override; void BuildUpdate(UpdateDataMapType& data_map) override; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 131663680..4c12a3c9b 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -53,6 +53,7 @@ #include "Player.h" #include "ReputationMgr.h" #include "ScriptMgr.h" +#include "SmartAI.h" #include "Spell.h" #include "SpellAuraEffects.h" #include "SpellAuras.h" @@ -4109,8 +4110,8 @@ void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool wi //LOG_DEBUG("entities.unit", "Interrupt spell for unit {}.", GetEntry()); Spell* spell = m_currentSpells[spellType]; if (spell - && (withDelayed || spell->getState() != SPELL_STATE_DELAYED) - && (withInstant || spell->GetCastTime() > 0 || spell->getState() == SPELL_STATE_CASTING)) // xinef: or spell is in casting state (channeled spells only) + && (withDelayed || spell->getState() != SPELL_STATE_DELAYED) + && (withInstant || spell->GetCastTime() > 0 || spell->getState() == SPELL_STATE_CASTING)) // xinef: or spell is in casting state (channeled spells only) { // for example, do not let self-stun aura interrupt itself if (!spell->IsInterruptable()) @@ -4128,6 +4129,15 @@ void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool wi m_currentSpells[spellType] = nullptr; spell->SetReferencedFromCurrent(false); } + + // SAI creatures only + // Start chasing victim if they are spell casters (at least one SMC spell) if interrupted/silenced. + if (IsCreature()) + { + if (SmartAI* ai = dynamic_cast(ToCreature()->AI())) + if (ai->CanChaseOnInterrupt()) + ai->SetCombatMove(true); + } } } diff --git a/src/server/game/Grids/GridObjectLoader.cpp b/src/server/game/Grids/GridObjectLoader.cpp index 6a5b4b736..d8b39ebd6 100644 --- a/src/server/game/Grids/GridObjectLoader.cpp +++ b/src/server/game/Grids/GridObjectLoader.cpp @@ -64,15 +64,28 @@ void GridObjectLoader::LoadGameObjects(CellGuidSet const& guid_set, Map* map) for (ObjectGuid::LowType const& guid : guid_set) { GameObjectData const* data = sObjectMgr->GetGameObjectData(guid); - GameObject* obj = data && sObjectMgr->IsGameObjectStaticTransport(data->id) ? new StaticTransport() : new GameObject(); - if (!obj->LoadFromDB(guid, map)) + if (data && sObjectMgr->IsGameObjectStaticTransport(data->id)) { - delete obj; - continue; - } + StaticTransport* transport = new StaticTransport(); - AddObjectHelper(map, obj); + // Special case for static transports - we are loaded via grids + // but we do not want to actually be stored in the grid + if (!transport->LoadGameObjectFromDB(guid, map, true)) + delete transport; + } + else + { + GameObject* obj = new GameObject(); + + if (!obj->LoadFromDB(guid, map)) + { + delete obj; + continue; + } + + AddObjectHelper(map, obj); + } } } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 3fede6ffc..b4b2331e1 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -28,6 +28,7 @@ #include "LFGMgr.h" #include "Log.h" #include "MapMgr.h" +#include "MiscPackets.h" #include "ObjectMgr.h" #include "Opcodes.h" #include "Player.h" @@ -2059,6 +2060,16 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* return GroupJoinBattlegroundResult(bgTemplate->GetBgTypeID()); } +void Group::DoMinimapPing(ObjectGuid sourceGuid, float mapX, float mapY) +{ + WorldPackets::Misc::MinimapPing minimapPing; + minimapPing.SourceGuid = sourceGuid; + minimapPing.MapX = mapX; + minimapPing.MapY = mapY; + + BroadcastPacket(minimapPing.Write(), true, -1, sourceGuid); +} + //=================================================== //============== Roll =============================== //=================================================== diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index e07360342..ff51131bf 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -255,6 +255,8 @@ public: void SetBattlefieldGroup(Battlefield* bf); GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const* bgTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot); + void DoMinimapPing(ObjectGuid sourceGuid, float mapX, float mapY); + void ChangeMembersGroup(ObjectGuid guid, uint8 group); void SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid); void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 0ac318319..ec5ca110f 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1175,6 +1175,10 @@ void WorldSession::HandlePlayerLoginToCharInWorld(Player* pCurrChar) pCurrChar->GetMap()->SendInitTransports(pCurrChar); pCurrChar->GetMap()->SendInitSelf(pCurrChar); pCurrChar->GetMap()->SendZoneDynamicInfo(pCurrChar); + + // If we are logging into an existing player, simply clear visibility references + // so player will receive a fresh list of new objects on the next vis update. + pCurrChar->GetObjectVisibilityContainer().CleanVisibilityReferences(); pCurrChar->UpdateObjectVisibility(false); pCurrChar->CleanupChannels(); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index ee4e0676a..c8f14779b 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -22,6 +22,7 @@ #include "LFGMgr.h" #include "Language.h" #include "Log.h" +#include "MapMgr.h" #include "MiscPackets.h" #include "ObjectMgr.h" #include "Opcodes.h" @@ -522,24 +523,17 @@ void WorldSession::HandleLootRoll(WorldPacket& recvData) } } -void WorldSession::HandleMinimapPingOpcode(WorldPacket& recvData) +void WorldSession::HandleMinimapPingOpcode(WorldPackets::Misc::MinimapPingClient& packet) { - if (!GetPlayer()->GetGroup()) + if (!sMapMgr->IsValidMapCoord(GetPlayer()->GetMap()->GetId(), packet.MapX, packet.MapY)) return; - float x, y; - recvData >> x; - recvData >> y; + Group* group = GetPlayer()->GetGroup(); - /** error handling **/ - /********************/ + if (!group) + return; - // everything's fine, do it - WorldPacket data(MSG_MINIMAP_PING, (8 + 4 + 4)); - data << GetPlayer()->GetGUID(); - data << float(x); - data << float(y); - GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID()); + group->DoMinimapPing(GetPlayer()->GetGUID(), packet.MapX, packet.MapY); } void WorldSession::HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& packet) @@ -549,10 +543,8 @@ void WorldSession::HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& maximum = packet.Max; /** error handling **/ - if (minimum > maximum || maximum > 10000) // < 32768 for urand call - { + if (minimum > maximum || maximum > sWorld->getIntConfig(CONFIG_RANDOM_ROLL_MAXIMUM)) return; - } GetPlayer()->DoRandomRoll(minimum, maximum); } diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 0666af71c..604977301 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -24,6 +24,7 @@ #include "Opcodes.h" #include "Pet.h" #include "Player.h" +#include "QueryPackets.h" #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" @@ -32,62 +33,55 @@ void WorldSession::SendNameQueryOpcode(ObjectGuid guid) { CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid); - WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8 + 1 + 1 + 1 + 1 + 1 + 10)); - data << guid.WriteAsPacked(); + WorldPackets::Query::NameQueryResponse nameQueryResponse; + nameQueryResponse.Guid = guid.WriteAsPacked(); if (!playerData) { - data << uint8(1); // name unknown - SendPacket(&data); + nameQueryResponse.NameUnknown = true; + SendPacket(nameQueryResponse.Write()); return; } Player* player = ObjectAccessor::FindConnectedPlayer(guid); - data << uint8(0); // name known - data << playerData->Name; // played name - data << uint8(0); // realm name - only set for cross realm interaction (such as Battlegrounds) - data << uint8(player ? player->getRace() : playerData->Race); - data << uint8(playerData->Sex); - data << uint8(playerData->Class); + nameQueryResponse.NameUnknown = false; + nameQueryResponse.Name = playerData->Name; + nameQueryResponse.Race = player ? player->getRace() : playerData->Race; + nameQueryResponse.Sex = player ? player->getGender() : playerData->Sex; + nameQueryResponse.Class = player ? player->getClass() : playerData->Class; - // pussywizard: optimization - /*Player* player = ObjectAccessor::FindConnectedPlayer(guid); if (DeclinedName const* names = (player ? player->GetDeclinedNames() : nullptr)) { - data << uint8(1); // Name is declined - for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) - data << names->name[i]; + nameQueryResponse.Declined = true; + nameQueryResponse.DeclinedNames = *names; } - else*/ - data << uint8(0); // Name is not declined + else + nameQueryResponse.Declined = false; - SendPacket(&data); + SendPacket(nameQueryResponse.Write()); } -void WorldSession::HandleNameQueryOpcode(WorldPacket& recvData) +void WorldSession::HandleNameQueryOpcode(WorldPackets::Query::NameQuery& packet) { - ObjectGuid guid; - recvData >> guid; - // This is disable by default to prevent lots of console spam // LOG_INFO("network.opcode", "HandleNameQueryOpcode {}", guid); - SendNameQueryOpcode(guid); + SendNameQueryOpcode(packet.Guid); } -void WorldSession::HandleQueryTimeOpcode(WorldPacket& /*recvData*/) +void WorldSession::HandleTimeQueryOpcode(WorldPackets::Query::TimeQuery& /*packet*/) { - SendQueryTimeResponse(); + SendTimeQueryResponse(); } -void WorldSession::SendQueryTimeResponse() +void WorldSession::SendTimeQueryResponse() { auto timeResponse = sWorld->GetNextDailyQuestsResetTime() - GameTime::GetGameTime(); - WorldPacket data(SMSG_QUERY_TIME_RESPONSE, 4 + 4); - data << uint32(GameTime::GetGameTime().count()); - data << uint32(timeResponse.count()); - SendPacket(&data); + WorldPackets::Query::TimeQueryResponse timeQueryResponse; + timeQueryResponse.ServerTime = GameTime::GetGameTime().count(); + timeQueryResponse.TimeResponse = timeResponse.count(); + SendPacket(timeQueryResponse.Write()); } /// Only _static_ data is sent in this packet !!! @@ -402,13 +396,10 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPacket& recvData) } } -void WorldSession::HandleCorpseMapPositionQuery(WorldPacket& recvData) +void WorldSession::HandleCorpseMapPositionQuery(WorldPackets::Query::CorpseMapPositionQuery& /*packet*/) { LOG_DEBUG("network", "WORLD: Recv CMSG_CORPSE_MAP_POSITION_QUERY"); - uint32 unk; - recvData >> unk; - WorldPacket data(SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE, 4 + 4 + 4 + 4); data << float(0); data << float(0); diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp index eb6243b21..089546aa5 100644 --- a/src/server/game/Handlers/TicketHandler.cpp +++ b/src/server/game/Handlers/TicketHandler.cpp @@ -172,7 +172,7 @@ void WorldSession::HandleGMTicketDeleteOpcode(WorldPacket& /*recv_data*/) void WorldSession::HandleGMTicketGetTicketOpcode(WorldPacket& /*recv_data*/) { - SendQueryTimeResponse(); + SendTimeQueryResponse(); if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID())) { diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 4c05d182b..4d1004efb 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -345,7 +345,7 @@ bool Map::AddToMap(T* obj, bool checkTransport) } template<> -bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/) +bool Map::AddToMap(Transport* obj, bool /*checkTransport*/) { //TODO: Needs clean up. An object should not be added to map twice. if (obj->IsInWorld()) @@ -360,26 +360,22 @@ bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/) } Cell cell(cellCoord); - if (obj->isActiveObject()) - EnsureGridLoaded(cell); + EnsureGridLoaded(cell); obj->AddToWorld(); _transports.insert(obj); // Broadcast creation to players - if (!GetPlayers().IsEmpty()) + for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) { - for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + if (itr->GetSource()->GetTransport() != obj) { - if (itr->GetSource()->GetTransport() != obj) - { - UpdateData data; - obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource()); - WorldPacket packet; - data.BuildPacket(packet); - itr->GetSource()->SendDirectMessage(&packet); - } + UpdateData data; + obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource()); + WorldPacket packet; + data.BuildPacket(packet); + itr->GetSource()->SendDirectMessage(&packet); } } @@ -667,7 +663,7 @@ void Map::RemoveFromMap(T* obj, bool remove) } template<> -void Map::RemoveFromMap(MotionTransport* obj, bool remove) +void Map::RemoveFromMap(Transport* obj, bool remove) { obj->RemoveFromWorld(); @@ -697,8 +693,6 @@ void Map::RemoveFromMap(MotionTransport* obj, bool remove) obj->ResetMap(); - // Transports are never actually deleted, but it *should* be safe to clear - // from update list when removing from world RemoveObjectFromMapUpdateList(obj); if (remove) @@ -966,11 +960,10 @@ void Map::UnloadAll() for (TransportsContainer::iterator itr = _transports.begin(); itr != _transports.end();) { - MotionTransport* transport = *itr; + Transport* transport = *itr; ++itr; - transport->RemoveFromWorld(); - delete transport; + RemoveFromMap(transport, true); } _transports.clear(); @@ -1589,6 +1582,9 @@ void Map::SendInitSelf(Player* player) void Map::SendInitTransports(Player* player) { + if (_transports.empty()) + return; + // Hack to send out transports UpdateData transData; for (TransportsContainer::const_iterator itr = _transports.begin(); itr != _transports.end(); ++itr) @@ -1605,24 +1601,15 @@ void Map::SendInitTransports(Player* player) void Map::SendRemoveTransports(Player* player) { + if (_transports.empty()) + return; + // Hack to send out transports UpdateData transData; for (TransportsContainer::const_iterator itr = _transports.begin(); itr != _transports.end(); ++itr) if (*itr != player->GetTransport()) (*itr)->BuildOutOfRangeUpdateBlock(&transData); - // pussywizard: remove static transports from client - /*for (GuidUnorderedSet::const_iterator it = player->m_clientGUIDs.begin(); it != player->m_clientGUIDs.end(); ) - { - if ((*it).IsTransport()) - { - transData.AddOutOfRangeGUID(*it); - it = player->m_clientGUIDs.erase(it); - } - else - ++it; - }*/ - if (!transData.HasData()) return; @@ -1699,7 +1686,7 @@ void Map::DelayedUpdate(const uint32 t_diff) { for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();) { - MotionTransport* transport = *_transportsUpdateIter; + Transport* transport = *_transportsUpdateIter; ++_transportsUpdateIter; if (!transport->IsInWorld()) @@ -1744,7 +1731,7 @@ void Map::RemoveAllObjectsInRemoveList() RemoveFromMap((DynamicObject*)obj, true); break; case TYPEID_GAMEOBJECT: - if (MotionTransport* transport = obj->ToGameObject()->ToMotionTransport()) + if (Transport* transport = obj->ToGameObject()->ToTransport()) RemoveFromMap(transport, true); else RemoveFromMap(obj->ToGameObject(), true); diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index fb24b0924..f43111633 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -146,7 +146,7 @@ struct ZoneDynamicInfo typedef std::map CreatureGroupHolderType; typedef std::unordered_map ZoneDynamicInfoMap; -typedef std::set TransportsContainer; +typedef std::unordered_set TransportsContainer; enum EncounterCreditType : uint8 { @@ -479,7 +479,7 @@ public: _updateObjects.erase(obj); } - size_t GetUpdateObjectsCount() const { return _updateObjects.size(); } + size_t GetUpdatableObjectsCount() const { return _updatableObjectList.size(); } virtual std::string GetDebugInfo() const; @@ -535,7 +535,6 @@ protected: MapRefMgr m_mapRefMgr; MapRefMgr::iterator m_mapRefIter; - // Objects that must update even in inactive grids without activating them TransportsContainer _transports; TransportsContainer::iterator _transportsUpdateIter; diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp index ad319e943..f065ccf56 100644 --- a/src/server/game/Maps/TransportMgr.cpp +++ b/src/server/game/Maps/TransportMgr.cpp @@ -412,10 +412,8 @@ MotionTransport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType if (map && map->IsDungeon()) trans->m_zoneScript = map->ToInstanceMap()->GetInstanceScript(); - // xinef: transports are active so passengers can be relocated (grids must be loaded) - trans->setActive(true); HashMapHolder::Insert(trans); - trans->GetMap()->AddToMap(trans); + trans->GetMap()->AddToMap(trans); return trans; } diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp index be3bdb843..925e2c71a 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp @@ -139,6 +139,11 @@ void ScriptMgr::OnPlayerReputationRankChange(Player* player, uint32 factionID, R CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_REPUTATION_RANK_CHANGE, script->OnPlayerReputationRankChange(player, factionID, newRank, oldRank, increased)); } +void ScriptMgr::OnPlayerGiveReputation(Player* player, int32 factionID, float& amount, ReputationSource repSource) +{ + CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_GIVE_REPUTATION, script->OnPlayerGiveReputation(player, factionID, amount, repSource)); +} + void ScriptMgr::OnPlayerLearnSpell(Player* player, uint32 spellID) { CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_LEARN_SPELL, script->OnPlayerLearnSpell(player, spellID)); diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.h b/src/server/game/Scripting/ScriptDefines/PlayerScript.h index ca1a1445e..1686144fc 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.h +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.h @@ -211,6 +211,7 @@ enum PlayerHook PLAYERHOOK_CAN_RESURRECT, PLAYERHOOK_ON_CAN_GIVE_LEVEL, PLAYERHOOK_ON_SEND_LIST_INVENTORY, + PLAYERHOOK_ON_GIVE_REPUTATION, PLAYERHOOK_END }; @@ -285,6 +286,9 @@ public: // Called when a player's reputation rank changes (before it is actually changed) virtual void OnPlayerReputationRankChange(Player* /*player*/, uint32 /*factionID*/, ReputationRank /*newRank*/, ReputationRank /*olRank*/, bool /*increased*/) { } + // Called when a player gains Reputation (before anything is given) + virtual void OnPlayerGiveReputation(Player* /*player*/, int32 /*factionID*/, float& /*amount*/, ReputationSource /*repSource*/) { } + // Called when a player learned new spell virtual void OnPlayerLearnSpell(Player* /*player*/, uint32 /*spellID*/) {} diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index c0a3cf95c..dac1c0e85 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -334,6 +334,7 @@ public: /* PlayerScript */ void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource); bool OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental); void OnPlayerReputationRankChange(Player* player, uint32 factionID, ReputationRank newRank, ReputationRank oldRank, bool increased); + void OnPlayerGiveReputation(Player* player, int32 factionID, float& amount, ReputationSource repSource); void OnPlayerLearnSpell(Player* player, uint32 spellID); void OnPlayerForgotSpell(Player* player, uint32 spellID); void OnPlayerDuelRequest(Player* target, Player* challenger); diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h index 1e3457e1d..30aecbb6f 100644 --- a/src/server/game/Server/Packets/AllPackets.h +++ b/src/server/game/Server/Packets/AllPackets.h @@ -27,6 +27,7 @@ #include "LFGPackets.h" #include "MiscPackets.h" #include "PetPackets.h" +#include "QueryPackets.h" #include "TotemPackets.h" #include "WorldStatePackets.h" diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp index a418a517e..109845381 100644 --- a/src/server/game/Server/Packets/MiscPackets.cpp +++ b/src/server/game/Server/Packets/MiscPackets.cpp @@ -67,6 +67,21 @@ WorldPacket const* WorldPackets::Misc::Playsound::Write() return &_worldPacket; } +void WorldPackets::Misc::MinimapPingClient::Read() +{ + _worldPacket >> MapX; + _worldPacket >> MapY; +} + +WorldPacket const* WorldPackets::Misc::MinimapPing::Write() +{ + _worldPacket << SourceGuid; + _worldPacket << float(MapX); + _worldPacket << float(MapY); + + return &_worldPacket; +} + void WorldPackets::Misc::RandomRollClient::Read() { _worldPacket >> Min; diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index 6f991293f..7453ad7fc 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -93,6 +93,29 @@ namespace WorldPackets uint32 SoundKitID = 0; }; + class MinimapPingClient final : public ClientPacket + { + public: + MinimapPingClient(WorldPacket&& packet) : ClientPacket(MSG_MINIMAP_PING, std::move(packet)) {} + + void Read() override; + + float MapX = 0.0f; // Raw position coordinates + float MapY = 0.0f; + }; + + class MinimapPing final : public ServerPacket + { + public: + MinimapPing() : ServerPacket(MSG_MINIMAP_PING, 8 + 4 + 4) { } + + WorldPacket const* Write() override; + + ObjectGuid SourceGuid; + float MapX = 0.0f; + float MapY = 0.0f; + }; + class RandomRollClient final : public ClientPacket { public: diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp new file mode 100644 index 000000000..6efa96275 --- /dev/null +++ b/src/server/game/Server/Packets/QueryPackets.cpp @@ -0,0 +1,58 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "QueryPackets.h" + +void WorldPackets::Query::NameQuery::Read() +{ + _worldPacket >> Guid; +} + +WorldPacket const* WorldPackets::Query::NameQueryResponse::Write() +{ + _worldPacket << Guid; + _worldPacket << NameUnknown; + if (NameUnknown) + return &_worldPacket; + + _worldPacket << Name; + _worldPacket << RealmName; + _worldPacket << Race; + _worldPacket << Sex; + _worldPacket << Class; + _worldPacket << Declined; + if (Declined) + { + for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) + _worldPacket << DeclinedNames.name[i]; + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Query::TimeQueryResponse::Write() +{ + _worldPacket << ServerTime; + _worldPacket << TimeResponse; + + return &_worldPacket; +} + +void WorldPackets::Query::CorpseMapPositionQuery::Read() +{ + _worldPacket >> unk; +} diff --git a/src/server/game/Server/Packets/QueryPackets.h b/src/server/game/Server/Packets/QueryPackets.h new file mode 100644 index 000000000..85d7a76ce --- /dev/null +++ b/src/server/game/Server/Packets/QueryPackets.h @@ -0,0 +1,87 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef QueryPackets_h__ +#define QueryPackets_h__ + +#include "Packet.h" +#include "Unit.h" + +namespace WorldPackets +{ + namespace Query + { + class NameQuery final : public ClientPacket + { + public: + NameQuery(WorldPacket&& packet) : ClientPacket(CMSG_NAME_QUERY, std::move(packet)) {} + + void Read() override; + + ObjectGuid Guid; + }; + + class NameQueryResponse final : public ServerPacket + { + public: + NameQueryResponse() : ServerPacket(SMSG_NAME_QUERY_RESPONSE, 8 + 1 + 1 + 1 + 1 + 1 + 10) {} + + WorldPacket const* Write() override; + + PackedGuid Guid; + uint8 NameUnknown = false; + std::string_view Name; + std::string_view RealmName = ""; // Only set for cross realm interaction (such as Battlegrounds) + uint8 Race = RACE_NONE; + uint8 Sex = GENDER_MALE; + uint8 Class = CLASS_NONE; + uint8 Declined = false; + DeclinedName DeclinedNames; + }; + + class TimeQuery final : public ClientPacket + { + public: + TimeQuery(WorldPacket&& packet) : ClientPacket(CMSG_QUERY_TIME, std::move(packet)) {} + + void Read() override {}; + }; + + class TimeQueryResponse final : public ServerPacket + { + public: + TimeQueryResponse() : ServerPacket(SMSG_QUERY_TIME_RESPONSE, 4 + 4) {} + + WorldPacket const* Write() override; + + uint32 ServerTime; + uint32 TimeResponse; + }; + + class CorpseMapPositionQuery final : public ClientPacket + { + public: + CorpseMapPositionQuery(WorldPacket&& packet) : ClientPacket(CMSG_CORPSE_MAP_POSITION_QUERY, std::move(packet)) {} + + void Read() override; + + uint32 unk; + }; + } +} + +#endif // QueryPackets_h__ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 85bcb4186..bc12f7764 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -590,7 +590,7 @@ void OpcodeTable::Initialize() /*0x1CB*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFICATION, STATUS_NEVER); /*0x1CC*/ DEFINE_HANDLER(CMSG_PLAYED_TIME, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandlePlayedTime ); /*0x1CD*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYED_TIME, STATUS_NEVER); - /*0x1CE*/ DEFINE_HANDLER(CMSG_QUERY_TIME, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleQueryTimeOpcode ); + /*0x1CE*/ DEFINE_HANDLER(CMSG_QUERY_TIME, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTimeQueryOpcode ); /*0x1CF*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_NEVER); /*0x1D0*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOG_XPGAIN, STATUS_NEVER); /*0x1D1*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AURACASTLOG, STATUS_NEVER); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 55919f7ea..4e99a0a65 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -148,6 +148,7 @@ namespace WorldPackets namespace Misc { + class MinimapPingClient; class RandomRollClient; } @@ -159,6 +160,13 @@ namespace WorldPackets class PetSpellAutocast; class RequestPetInfo; } + + namespace Query + { + class NameQuery; + class TimeQuery; + class CorpseMapPositionQuery; + } } enum AccountDataType @@ -389,7 +397,7 @@ public: } void SendSetPhaseShift(uint32 phaseShift); - void SendQueryTimeResponse(); + void SendTimeQueryResponse(); void SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos = 0); void SendClientCacheVersion(uint32 version); @@ -680,9 +688,9 @@ public: // opcodes handlers void HandleGameObjectUseOpcode(WorldPacket& recPacket); void HandleGameobjectReportUse(WorldPacket& recvPacket); - void HandleNameQueryOpcode(WorldPacket& recvPacket); + void HandleNameQueryOpcode(WorldPackets::Query::NameQuery& packet); - void HandleQueryTimeOpcode(WorldPacket& recvPacket); + void HandleTimeQueryOpcode(WorldPackets::Query::TimeQuery& packet); void HandleCreatureQueryOpcode(WorldPacket& recvPacket); @@ -882,7 +890,7 @@ public: // opcodes handlers void HandleReclaimCorpseOpcode(WorldPacket& recvPacket); void HandleCorpseQueryOpcode(WorldPacket& recvPacket); - void HandleCorpseMapPositionQuery(WorldPacket& recvPacket); + void HandleCorpseMapPositionQuery(WorldPackets::Query::CorpseMapPositionQuery& packet); void HandleResurrectResponseOpcode(WorldPacket& recvPacket); void HandleSummonResponseOpcode(WorldPacket& recvData); @@ -953,7 +961,7 @@ public: // opcodes handlers void HandleWardenDataOpcode(WorldPacket& recvData); void HandleWorldTeleportOpcode(WorldPacket& recvData); - void HandleMinimapPingOpcode(WorldPacket& recvData); + void HandleMinimapPingOpcode(WorldPackets::Misc::MinimapPingClient& packet); void HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& packet); void HandleFarSightOpcode(WorldPacket& recvData); void HandleSetDungeonDifficultyOpcode(WorldPacket& recvData); diff --git a/src/server/game/World/WorldConfig.cpp b/src/server/game/World/WorldConfig.cpp index 7a0b1db40..c38b36ff0 100644 --- a/src/server/game/World/WorldConfig.cpp +++ b/src/server/game/World/WorldConfig.cpp @@ -492,6 +492,8 @@ void WorldConfig::BuildConfigCache() SetConfigValue(CONFIG_LEAVE_GROUP_ON_LOGOUT, "LeaveGroupOnLogout.Enabled", false); + SetConfigValue(CONFIG_RANDOM_ROLL_MAXIMUM, "Group.RandomRollMaximum", 1000000); + SetConfigValue(CONFIG_QUEST_POI_ENABLED, "QuestPOI.Enabled", true); SetConfigValue(CONFIG_CHANGE_FACTION_MAX_MONEY, "ChangeFaction.MaxMoney", 0); diff --git a/src/server/game/World/WorldConfig.h b/src/server/game/World/WorldConfig.h index 3776fcac9..475bed337 100644 --- a/src/server/game/World/WorldConfig.h +++ b/src/server/game/World/WorldConfig.h @@ -129,6 +129,7 @@ enum ServerConfigs CONFIG_ALLOW_JOIN_BG_AND_LFG, CONFIG_MISS_CHANCE_MULTIPLIER_ONLY_FOR_PLAYERS, CONFIG_LEAVE_GROUP_ON_LOGOUT, + CONFIG_RANDOM_ROLL_MAXIMUM, CONFIG_QUEST_POI_ENABLED, CONFIG_VMAP_BLIZZLIKE_PVP_LOS, CONFIG_VMAP_BLIZZLIKE_LOS_OPEN_WORLD, diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 3198936fa..a18e01e0b 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -73,7 +73,7 @@ public: { "hostile", HandleDebugHostileRefListCommand, SEC_ADMINISTRATOR, Console::No }, { "anim", HandleDebugAnimCommand, SEC_ADMINISTRATOR, Console::No }, { "arena", HandleDebugArenaCommand, SEC_ADMINISTRATOR, Console::No }, - { "bg", HandleDebugBattlegroundCommand, SEC_ADMINISTRATOR, Console::No }, + { "bg", HandleDebugBattlegroundCommand, SEC_ADMINISTRATOR, Console::Yes}, { "cooldown", HandleDebugCooldownCommand, SEC_ADMINISTRATOR, Console::No }, { "getitemstate", HandleDebugGetItemStateCommand, SEC_ADMINISTRATOR, Console::No }, { "lootrecipient", HandleDebugGetLootRecipientCommand, SEC_ADMINISTRATOR, Console::No }, @@ -92,7 +92,7 @@ public: { "update", HandleDebugUpdateCommand, SEC_ADMINISTRATOR, Console::No }, { "itemexpire", HandleDebugItemExpireCommand, SEC_ADMINISTRATOR, Console::No }, { "areatriggers", HandleDebugAreaTriggersCommand, SEC_ADMINISTRATOR, Console::No }, - { "lfg", HandleDebugDungeonFinderCommand, SEC_ADMINISTRATOR, Console::No }, + { "lfg", HandleDebugDungeonFinderCommand, SEC_ADMINISTRATOR, Console::Yes}, { "los", HandleDebugLoSCommand, SEC_ADMINISTRATOR, Console::No }, { "moveflags", HandleDebugMoveflagsCommand, SEC_ADMINISTRATOR, Console::No }, { "unitstate", HandleDebugUnitStateCommand, SEC_ADMINISTRATOR, Console::No }, @@ -1351,7 +1351,7 @@ public: map->GetId(), map->GetMapName(), map->GetInstanceId(), uint64(map->GetObjectsStore().Size()), uint64(map->GetObjectsStore().Size()), - uint64(map->GetUpdateObjectsCount())); + uint64(map->GetUpdatableObjectsCount())); CreatureCountWorker worker; TypeContainerVisitor visitor(worker); diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_tenris_mirkblood.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_tenris_mirkblood.cpp new file mode 100644 index 000000000..518a46055 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_tenris_mirkblood.cpp @@ -0,0 +1,375 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "karazhan.h" +#include "AreaTriggerScript.h" +#include "CreatureScript.h" +#include "GameObjectAI.h" +#include "GameObjectScript.h" +#include "Player.h" +#include "ScriptedCreature.h" +#include "SpellInfo.h" +#include "SpellScript.h" +#include "SpellScriptLoader.h" +#include "UnitAI.h" + +enum Text +{ + SAY_APPROACH = 0, + SAY_AGGRO = 1, + SAY_SUMMON = 2 +}; + +enum Spells +{ + SPELL_BLOOD_MIRROR0 = 50844, + SPELL_BLOOD_MIRROR1 = 50845, + SPELL_BLOOD_MIRROR_TARGET_PICKER = 50883, + SPELL_BLOOD_MIRROR_TRANSITION_VISUAL = 50910, + SPELL_BLOOD_MIRROR_DAMAGE = 50846, + + SPELL_BLOOD_TAP = 51135, + + SPELL_BLOOD_SWOOP = 50922, + SPELL_DASH_GASH_PRE_SPELL = 50923, + SPELL_DASH_GASH_RETURN_TO_TANK = 50924, + // SPELL_DASH_GASH_RETURN_TO_TANK_PRE_SPELL = 50925, + // SPELL_DASH_GASH_RETURN_TO_TANK_PRE_SPELL_ROOT = 50932, + + SPELL_DESPAWN_SANGUINE_SPIRIT_VISUAL = 51214, + SPELL_DESPAWN_SANGUINE_SPIRITS = 51212, + SPELL_SANGUINE_SPIRIT_AURA = 50993, + SPELL_SANGUINE_SPIRIT_PRE_AURA = 51282, + SPELL_SANGUINE_SPIRIT_PRE_AURA2 = 51283, + SPELL_SUMMON_SANGUINE_SPIRIT0 = 50996, + SPELL_SUMMON_SANGUINE_SPIRIT1 = 50998, + // SPELL_SUMMON_SANGUINE_SPIRIT2 = 51204, + SPELL_SUMMON_SANGUINE_SPIRIT_MISSILE_BURST = 51208, + SPELL_SUMMON_SANGUINE_SPIRIT_SHORT_MISSILE_BURST = 51280, + SPELL_SUMMON_SANGUINE_SPIRIT_ON_KILL = 51205, + SPELL_EXSANGUINATE = 51013, + SPELL_DUMMY_NUKE_RANGE_SELF = 51106, +}; + +enum Events +{ + EVENT_SAY = 1, + EVENT_FLAG = 2 +}; + +struct boss_tenris_mirkblood : public BossAI +{ + boss_tenris_mirkblood(Creature* creature) : BossAI(creature, DATA_MIRKBLOOD) + { + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + } + + void Reset() override + { + _Reset(); + + me->SetImmuneToPC(true); + + ScheduleHealthCheckEvent(50, [&] { + Talk(SAY_SUMMON); + DoCast(SPELL_SUMMON_SANGUINE_SPIRIT_MISSILE_BURST); + }); + + ScheduleHealthCheckEvent(45, [&] { + ScheduleTimedEvent(10s, 15s, [&] { + DoCast(SPELL_BLOOD_TAP); + }, 15s, 40s); + }); + } + + void JustEngagedWith(Unit* /*who*/) override + { + DoZoneInCombat(); + + ScheduleTimedEvent(1s, 5s, [&] { + // Blood Mirror + DoCast(SPELL_BLOOD_MIRROR_TARGET_PICKER); + }, 20s, 50s); + ScheduleTimedEvent(30s, [&] { + // Blood Swoop + DoCast(SPELL_DASH_GASH_PRE_SPELL); + }, 15s, 40s); + ScheduleTimedEvent(6s, 15s, [&] { + // Sanguine Spirit + DoCast(SPELL_SUMMON_SANGUINE_SPIRIT_SHORT_MISSILE_BURST); + }, 6s, 15s); + } + + void KilledUnit(Unit* victim) override + { + if (!victim) + return; + + DoCast(victim, SPELL_SUMMON_SANGUINE_SPIRIT_ON_KILL); + } + + void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damageType, SpellSchoolMask damageSchoolMask) override + { + BossAI::DamageTaken(attacker, damage, damageType, damageSchoolMask); + + if (!me->HasAura(SPELL_BLOOD_MIRROR0)) + return; + + if (!_mirrorTarget) + return; + + int32 damageTaken = damage; + + me->CastCustomSpell(_mirrorTarget, SPELL_BLOOD_MIRROR_DAMAGE, &damageTaken, &damageTaken, &damageTaken, true, nullptr, nullptr, me->GetGUID()); + } + + void SpellHit(Unit* caster, SpellInfo const* spell) override + { + if (spell->Id == SPELL_BLOOD_MIRROR0 && caster != me) + _mirrorTarget = caster; + } + + void EnterEvadeMode(EvadeReason why) override + { + _EnterEvadeMode(why); + me->SetImmuneToPC(false); + } + +private: + Unit* _mirrorTarget = nullptr; +}; + +struct npc_sanguine_spirit : public ScriptedAI +{ + npc_sanguine_spirit(Creature* creature) : ScriptedAI(creature) {} + + void Reset() override + { + scheduler.CancelAll(); + me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_ALL, true); + + me->SetReactState(REACT_PASSIVE); + + DoCastSelf(SPELL_SANGUINE_SPIRIT_PRE_AURA); + + scheduler.Schedule(5s, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_SANGUINE_SPIRIT_PRE_AURA2); + }).Schedule(3s, [this](TaskContext /*context*/) + { + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + DoCastSelf(SPELL_SANGUINE_SPIRIT_AURA); + }); + } + + void UpdateAI(uint32 diff) override + { + scheduler.Update(diff); + UpdateVictim(); + } +}; + +class spell_mirkblood_blood_mirror_target_picker : public SpellScript +{ + PrepareSpellScript(spell_mirkblood_blood_mirror_target_picker) + + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_BLOOD_MIRROR0, SPELL_BLOOD_MIRROR1, SPELL_BLOOD_MIRROR_TRANSITION_VISUAL }); + } + + void HandleHit() + { + Unit* caster = GetCaster(); + + if (!caster->ToCreature()) + return; + + Unit* target = caster->GetAI()->SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, false); + + if (!target) // Only Blood Mirror the tank if they're the only one around + target = caster->GetVictim(); + + if (!target) + return; + + caster->CastSpell(caster, SPELL_BLOOD_MIRROR_TRANSITION_VISUAL, TRIGGERED_FULL_MASK); + caster->CastSpell(target, SPELL_BLOOD_MIRROR_TRANSITION_VISUAL, TRIGGERED_FULL_MASK); + + caster->AddAura(SPELL_BLOOD_MIRROR1, caster); // Should be a cast, but channeled spell results in either Mirkblood or player being unactionable + caster->AddAura(SPELL_BLOOD_MIRROR1, target); // Adding aura manually causes visual to not appear properly, but better than breaking gameplay + + target->CastSpell(caster, SPELL_BLOOD_MIRROR0); // Clone player + } + + void Register() override + { + OnCast += SpellCastFn(spell_mirkblood_blood_mirror_target_picker::HandleHit); + } +}; + +class spell_mirkblood_dash_gash_return_to_tank_pre_spell : public SpellScript +{ + PrepareSpellScript(spell_mirkblood_dash_gash_return_to_tank_pre_spell) + + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_DASH_GASH_RETURN_TO_TANK }); + } + + void HandleCast() + { + if (!GetCaster() || !GetCaster()->GetThreatMgr().GetCurrentVictim()) + return; + // Probably wrong, maybe don't charge if would charge the same target? + if (GetCaster()->GetDistance2d(GetCaster()->GetThreatMgr().GetCurrentVictim()) < 5.0f) + return; + + GetCaster()->CastSpell(GetCaster()->GetVictim(), SPELL_DASH_GASH_RETURN_TO_TANK); + } + + void Register() override + { + OnCast += SpellCastFn(spell_mirkblood_dash_gash_return_to_tank_pre_spell::HandleCast); + } +}; + +class spell_mirkblood_exsanguinate : public SpellScript +{ + PrepareSpellScript(spell_mirkblood_exsanguinate) + + void CalculateDamage() + { + if (!GetHitUnit()) + return; + + SetHitDamage(std::max((GetHitUnit()->GetHealth() * 0.66f), 2000.0f)); + } + + void Register() override + { + OnHit += SpellHitFn(spell_mirkblood_exsanguinate::CalculateDamage); + } +}; + +class at_karazhan_mirkblood_approach : public AreaTriggerScript +{ +public: + at_karazhan_mirkblood_approach() : AreaTriggerScript("at_karazhan_mirkblood_approach") {} + + bool OnTrigger(Player* player, AreaTrigger const* /*trigger*/) override + { + if (InstanceScript* instance = player->GetInstanceScript()) + if (instance->GetBossState(DATA_MIRKBLOOD) != DONE) + if (Creature* mirkblood = instance->GetCreature(DATA_MIRKBLOOD)) + mirkblood->AI()->Talk(SAY_APPROACH, player); + + return false; + } +}; + +class at_karazhan_mirkblood_entrance : public AreaTriggerScript +{ +public: + at_karazhan_mirkblood_entrance() : AreaTriggerScript("at_karazhan_mirkblood_entrance") {} + + bool OnTrigger(Player* player, AreaTrigger const* /*trigger*/) override + { + if (InstanceScript* instance = player->GetInstanceScript()) + if (instance->GetBossState(DATA_MIRKBLOOD) != DONE) + if (Creature* mirkblood = instance->GetCreature(DATA_MIRKBLOOD)) + mirkblood->SetImmuneToPC(false); + + return false; + } +}; + +class go_blood_drenched_door : public GameObjectScript +{ +public: + go_blood_drenched_door() : GameObjectScript("go_blood_drenched_door") {} + + struct go_blood_drenched_doorAI : public GameObjectAI + { + go_blood_drenched_doorAI(GameObject* go) : GameObjectAI(go) {} + + EventMap events; + Creature* mirkblood; + Player* opener; + + bool GossipHello(Player* player, bool /*reportUse*/) override + { + events.Reset(); + + if (InstanceScript* instance = player->GetInstanceScript()) + if (instance->GetBossState(DATA_MIRKBLOOD) != DONE) + { + opener = player; + mirkblood = instance->GetCreature(DATA_MIRKBLOOD); + + events.ScheduleEvent(EVENT_SAY, 1s); + events.ScheduleEvent(EVENT_FLAG, 5s); + me->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); + } + + return true; + } + + void UpdateAI(uint32 diff) override + { + if (events.Empty()) + return; + + events.Update(diff); + switch (events.ExecuteEvent()) + { + case EVENT_SAY: + if (!mirkblood) + return; + mirkblood->AI()->Talk(SAY_AGGRO, opener); + break; + case EVENT_FLAG: + if (!mirkblood) + return; + mirkblood->SetImmuneToPC(false); + me->Delete(); + break; + } + } + }; + + GameObjectAI* GetAI(GameObject* go) const override + { + return new go_blood_drenched_doorAI(go); + } +}; + +void AddSC_boss_tenris_mirkblood() +{ + RegisterKarazhanCreatureAI(boss_tenris_mirkblood); + RegisterKarazhanCreatureAI(npc_sanguine_spirit); + RegisterSpellScript(spell_mirkblood_blood_mirror_target_picker); + RegisterSpellScript(spell_mirkblood_dash_gash_return_to_tank_pre_spell); + RegisterSpellScript(spell_mirkblood_exsanguinate); + new at_karazhan_mirkblood_approach(); + new at_karazhan_mirkblood_entrance(); + new go_blood_drenched_door(); +} diff --git a/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp index 2f4f27dae..a283e65cc 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/instance_karazhan.cpp @@ -47,6 +47,7 @@ ObjectData const creatureData[] = { NPC_JULIANNE, DATA_JULIANNE }, { NPC_NIGHTBANE, DATA_NIGHTBANE }, { NPC_TERESTIAN_ILLHOOF, DATA_TERESTIAN }, + { NPC_TENRIS_MIRKBLOOD, DATA_MIRKBLOOD }, { 0, 0 } }; diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h index 4e0d57f4b..890fdcf2d 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.h @@ -73,7 +73,9 @@ enum KZDataTypes DATA_ROAR = 41, DATA_STRAWMAN = 42, DATA_TINHEAD = 43, - DATA_TITO = 44 + DATA_TITO = 44, + + DATA_MIRKBLOOD = 45 }; enum KZOperaEvents @@ -135,7 +137,9 @@ enum KZCreatures // Malchezaar Helpers NPC_INFERNAL_TARGET = 17644, - NPC_INFERNAL_RELAY = 17645 + NPC_INFERNAL_RELAY = 17645, + + NPC_TENRIS_MIRKBLOOD = 28194 }; diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp index 2858a5cf6..ddd75f48a 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp @@ -1181,6 +1181,26 @@ class spell_kiljaeden_dragon_breath : public SpellScript } }; +// 45848 - Shield of the Blue +class spell_kiljaeden_shield_of_the_blue : public AuraScript +{ + PrepareAuraScript(spell_kiljaeden_shield_of_the_blue); + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* target = GetTarget()) + { + target->RemoveAurasDueToSpell(SPELL_FIRE_BLOOM); + target->RemoveMovementImpairingAuras(false); + } + } + + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_kiljaeden_shield_of_the_blue::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); + } +}; + void AddSC_boss_kiljaeden() { RegisterSunwellPlateauCreatureAI(npc_kiljaeden_controller); @@ -1196,4 +1216,5 @@ void AddSC_boss_kiljaeden() RegisterSpellScript(spell_kiljaeden_armageddon_periodic_aura); RegisterSpellScript(spell_kiljaeden_armageddon_missile); RegisterSpellScript(spell_kiljaeden_dragon_breath); + RegisterSpellScript(spell_kiljaeden_shield_of_the_blue); } diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp index 67360281a..b92b35215 100644 --- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp +++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp @@ -78,6 +78,7 @@ void AddSC_bosses_opera(); void AddSC_boss_netherspite(); void AddSC_karazhan(); void AddSC_boss_nightbane(); +void AddSC_boss_tenris_mirkblood(); void AddSC_boss_felblood_kaelthas(); // Magister's Terrace void AddSC_boss_selin_fireheart(); void AddSC_boss_vexallus(); @@ -229,6 +230,7 @@ void AddEasternKingdomsScripts() AddSC_boss_netherspite(); AddSC_karazhan(); AddSC_boss_nightbane(); + AddSC_boss_tenris_mirkblood(); AddSC_boss_felblood_kaelthas(); // Magister's Terrace AddSC_boss_selin_fireheart(); AddSC_boss_vexallus(); diff --git a/src/server/scripts/Pet/pet_dk.cpp b/src/server/scripts/Pet/pet_dk.cpp index c2eedba77..1a8a81540 100644 --- a/src/server/scripts/Pet/pet_dk.cpp +++ b/src/server/scripts/Pet/pet_dk.cpp @@ -245,6 +245,20 @@ struct npc_pet_dk_ghoul : public CombatAI { npc_pet_dk_ghoul(Creature* c) : CombatAI(c) { } + void IsSummonedBy(WorldObject* summoner) override + { + if (!summoner || !summoner->IsPlayer()) + return; + + Player* player = summoner->ToPlayer(); + + if (Unit* victim = player->GetVictim()) + { + me->Attack(victim, true); + me->GetMotionMaster()->MoveChase(victim); + } + } + void JustDied(Unit* /*who*/) override { if (me->IsGuardian() || me->IsSummon()) @@ -278,6 +292,28 @@ struct npc_pet_dk_army_of_the_dead : public CombatAI CombatAI::InitializeAI(); ((Minion*)me)->SetFollowAngle(rand_norm() * 2 * M_PI); } + + void IsSummonedBy(WorldObject* summoner) override + { + if (Unit* owner = summoner->ToUnit()) + { + Unit* victim = owner->GetVictim(); + + if (victim && me->IsValidAttackTarget(victim)) + { + AttackStart(victim); + } + else + { + // If there is no valid target, attack the nearest enemy within 30m + if (Unit* nearest = me->SelectNearbyTarget(nullptr, 30.0f)) + { + if (me->IsValidAttackTarget(nearest)) + AttackStart(nearest); + } + } + } + } }; struct npc_pet_dk_dancing_rune_weapon : public NullCreatureAI diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index d1d371710..b2d312a5a 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -345,7 +345,7 @@ class spell_dk_death_and_decay_aura : public AuraScript if (GetCaster() && GetTarget()) { int32 basePoints0 = aurEff->GetAmount(); - GetCaster()->CastCustomSpell(GetTarget(), SPELL_DK_DEATH_AND_DECAY_TRIGGER, &basePoints0, nullptr, nullptr, false, 0, aurEff); + GetCaster()->CastCustomSpell(GetTarget(), SPELL_DK_DEATH_AND_DECAY_TRIGGER, &basePoints0, nullptr, nullptr, true, 0, aurEff); } } diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index 8b75e97dc..c7bded8be 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -187,6 +187,17 @@ enum ReputationRank : uint8 REP_EXALTED = 7 }; +enum ReputationSource +{ + REPUTATION_SOURCE_KILL, + REPUTATION_SOURCE_QUEST, + REPUTATION_SOURCE_DAILY_QUEST, + REPUTATION_SOURCE_WEEKLY_QUEST, + REPUTATION_SOURCE_MONTHLY_QUEST, + REPUTATION_SOURCE_REPEATABLE_QUEST, + REPUTATION_SOURCE_SPELL +}; + enum FactionTemplates { FACTION_NONE = 0,