Merge pull request #7 from azerothcore/master

Merge
This commit is contained in:
kadeshar
2025-08-27 21:04:10 +02:00
committed by GitHub
79 changed files with 2648 additions and 291 deletions
+2 -1
View File
@@ -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
+84 -11
View File
@@ -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
```
+144
View File
@@ -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"
+324 -65
View File
@@ -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: <needs manual configuration>"
echo " Args: <needs manual configuration>"
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 <service-name> [options]"
echo " $base_name delete <service-name>"
echo " $base_name list [provider]"
echo " $base_name restore"
echo " $base_name start|stop|restart|status <service-name>"
echo " $base_name logs <service-name> [--follow]"
echo " $base_name attach <service-name>"
@@ -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')
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_info" '. += [$service]' "$tmp_file" > "$tmp_file.new"
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
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
@@ -499,10 +726,6 @@ 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
systemctl daemon-reload
@@ -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
@@ -1207,6 +1445,11 @@ function attach_to_service() {
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"
# Auto-detect session manager and attach accordingly
@@ -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}"
@@ -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));
@@ -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;
@@ -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');
@@ -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);
@@ -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);
@@ -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;
@@ -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);
@@ -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');
@@ -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');
@@ -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 <Horde Ambassador>
(@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 <Copper Bar Collector>
(@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 <Iron Bar Collector>
(@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 <Thorium Bar Collector>
(@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 <Stranglekelp Collector>
(@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 <Purple Lotus Collector>
(@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 <Arthas' Tears Collector>
(@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 <Light Leather Collector>
(@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 <Medium Leather Collector>
(@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 <Thick Leather Collector>
(@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 <Linen Bandage Collector>
(@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 <Silk Bandage Collector>
(@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 <Runecloth Bandage Collector>
(@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 <Rainbow Fin Albacore Collector>
(@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 <Roast Raptor Collector>
(@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 <Spotted Yellowtail Collector>
(@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 <War Effort Commander>
-- 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 <Alliance Ambassador>
(@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 <Thick Leather Collector>
(@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 <Lean Wolf Steak Collector>
(@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 <Spotted Yellowtail Collector>
(@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 <Baked Salmon Collector>
(@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 <Copper Bar Collector>
(@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 <Tin Bar Collector>
(@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 <Mithril Bar Collector>
(@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 <Peacebloom Collector>
(@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 <Firebloom Collector>
(@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 <Purple Lotus Collector>
(@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 <Heavy Leather Collector>
(@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 <Rugged Leather Collector>
(@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 <Wool Bandage Collector>
(@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 <Mageweave Bandage Collector>
(@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 <Runecloth Bandage Collector>
(@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 Commander>
-- 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 <War Effort Recruiter>
(@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 <War Effort Recruiter>
(@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 <War Effort Recruiter>
(@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 <War Effort Recruiter>
(@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 <War Effort Recruiter>
(@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 <War Effort Recruiter>
-- 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 <Darkspear Commendations>
(@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 <Darnassus Commendations>
(@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 <Gnomeregan Commendations>
(@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 <Ironforge Commendations>
(@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 <Orgrimmar Commendations>
(@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 <Stormwind Commendations>
(@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 <Thunder Bluff Commendations>
(@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 <Undercity Commendations>
-- 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);
+465
View File
@@ -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);
+103
View File
@@ -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);
@@ -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;
@@ -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');
@@ -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);
@@ -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));
@@ -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;
@@ -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;
+4 -5
View File
@@ -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;
}
+3 -5
View File
@@ -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;
}
@@ -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
#
###################################################################################################
@@ -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);
@@ -72,6 +72,8 @@ SmartAI::SmartAI(Creature* c) : CreatureAI(c)
mcanSpawn = true;
_chaseOnInterrupt = false;
// Xinef: Vehicle conditions
m_ConditionsTimer = 0;
if (me->GetVehicleKit())
@@ -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
@@ -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:
@@ -201,12 +201,31 @@ void SmartAIMgr::LoadSmartAIFromDB()
}
}
else
{
switch (source_type)
{
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;
}
}
temp.source_type = source_type;
@@ -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);
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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);
}
}
@@ -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())
@@ -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<ObjectGuid::LowType/*memberDBGUID*/, FormationInfo /*formationInfo*/> CreatureGroupInfoType;
@@ -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())
@@ -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)
+7 -1
View File
@@ -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);
@@ -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;
@@ -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<float>(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<float>(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))
+6 -14
View File
@@ -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);
@@ -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<std::string_view> tokens = Acore::Tokenize(data, ' ', false);
result.reserve(tokens.size());
for (auto const& token : tokens)
{
if (token.empty())
continue;
if (auto parsed = Acore::StringTo<uint32>(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<std::string>();
if (rowSource != source)
continue;
std::string data = fields[1].Get<std::string>();
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<size_t>(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>();
std::string data = fields[1].Get<std::string>();
std::vector<std::string_view> 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<uint32>(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<size_t>(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<size_t>(index) + 1;
@@ -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<PlayerSetting> PlayerSettingVector;
typedef std::map<std::string, PlayerSettingVector> 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
@@ -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,6 +3096,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
pBag->RemoveItem(slot, update);
// Xinef: item is removed, remove loot from storage if any
if (ItemTemplate const* proto = pItem->GetTemplate())
if (proto->HasFlag(ITEM_FLAG_HAS_LOOT))
sLootItemStorage->RemoveStoredLoot(pItem->GetGUID());
@@ -1646,9 +1646,6 @@ template <>
inline void UpdateVisibilityOf_helper(Player* player, GameObject* target,
std::vector<Unit*>& /*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);
}
@@ -607,12 +607,12 @@ void MotionTransport::DelayedTeleportTransport()
}
Map* newMap = sMapMgr->CreateBaseMap(newMapId);
GetMap()->RemoveFromMap<MotionTransport>(this, false);
GetMap()->RemoveFromMap<Transport>(this, false);
newMap->LoadGrid(x, y); // xinef: load before adding passengers to new map
SetMap(newMap);
Relocate(x, y, z, o);
GetMap()->AddToMap<MotionTransport>(this);
GetMap()->AddToMap<Transport>(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<HighGuid::Transport>(), entry, map, phaseMask, x, y, z, ang, data->rotation, animprogress, go_state, artKit))
return false;
if (addToMap && !GetMap()->AddToMap<Transport>(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();
}
@@ -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;
+10
View File
@@ -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"
@@ -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<SmartAI*>(ToCreature()->AI()))
if (ai->CanChaseOnInterrupt())
ai->SetCombatMove(true);
}
}
}
+14 -1
View File
@@ -64,7 +64,19 @@ 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 (data && sObjectMgr->IsGameObjectStaticTransport(data->id))
{
StaticTransport* transport = new StaticTransport();
// 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))
{
@@ -75,6 +87,7 @@ void GridObjectLoader::LoadGameObjects(CellGuidSet const& guid_set, Map* map)
AddObjectHelper<GameObject>(map, obj);
}
}
}
void GridObjectLoader::LoadAllCellsInGrid()
{
+11
View File
@@ -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 ===============================
//===================================================
+2
View File
@@ -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);
@@ -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();
+8 -16
View File
@@ -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);
}
+25 -34
View File
@@ -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);
+1 -1
View File
@@ -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()))
{
+12 -25
View File
@@ -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,7 +360,6 @@ bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/)
}
Cell cell(cellCoord);
if (obj->isActiveObject())
EnsureGridLoaded(cell);
obj->AddToWorld();
@@ -368,8 +367,6 @@ bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/)
_transports.insert(obj);
// Broadcast creation to players
if (!GetPlayers().IsEmpty())
{
for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
{
if (itr->GetSource()->GetTransport() != obj)
@@ -381,7 +378,6 @@ bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/)
itr->GetSource()->SendDirectMessage(&packet);
}
}
}
return true;
}
@@ -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>(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);
+2 -3
View File
@@ -146,7 +146,7 @@ struct ZoneDynamicInfo
typedef std::map<uint32/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHolderType;
typedef std::unordered_map<uint32 /*zoneId*/, ZoneDynamicInfo> ZoneDynamicInfoMap;
typedef std::set<MotionTransport*> TransportsContainer;
typedef std::unordered_set<Transport*> 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;
+1 -3
View File
@@ -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<MotionTransport>::Insert(trans);
trans->GetMap()->AddToMap<MotionTransport>(trans);
trans->GetMap()->AddToMap<Transport>(trans);
return trans;
}
@@ -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));
@@ -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*/) {}
+1
View File
@@ -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);
@@ -27,6 +27,7 @@
#include "LFGPackets.h"
#include "MiscPackets.h"
#include "PetPackets.h"
#include "QueryPackets.h"
#include "TotemPackets.h"
#include "WorldStatePackets.h"
@@ -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;
@@ -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:
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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__
+1 -1
View File
@@ -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);
+13 -5
View File
@@ -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);
+2
View File
@@ -492,6 +492,8 @@ void WorldConfig::BuildConfigCache()
SetConfigValue<bool>(CONFIG_LEAVE_GROUP_ON_LOGOUT, "LeaveGroupOnLogout.Enabled", false);
SetConfigValue<uint32>(CONFIG_RANDOM_ROLL_MAXIMUM, "Group.RandomRollMaximum", 1000000);
SetConfigValue<bool>(CONFIG_QUEST_POI_ENABLED, "QuestPOI.Enabled", true);
SetConfigValue<uint32>(CONFIG_CHANGE_FACTION_MAX_MONEY, "ChangeFaction.MaxMoney", 0);
+1
View File
@@ -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,
+3 -3
View File
@@ -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<Creature>()),
uint64(map->GetObjectsStore().Size<GameObject>()),
uint64(map->GetUpdateObjectsCount()));
uint64(map->GetUpdatableObjectsCount()));
CreatureCountWorker worker;
TypeContainerVisitor<CreatureCountWorker, MapStoredObjectTypesContainer> visitor(worker);
@@ -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 <http://www.gnu.org/licenses/>.
*/
#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();
}
@@ -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 }
};
@@ -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
};
@@ -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);
}
@@ -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();
+36
View File
@@ -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
+1 -1
View File
@@ -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);
}
}
+11
View File
@@ -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,