From 2931c00bd483e823250c224a8b7738b4d7f260d6 Mon Sep 17 00:00:00 2001 From: Aleos Date: Wed, 12 Feb 2020 08:26:59 -0500 Subject: [PATCH] Implemented the Battleground Queue System (#3995) * Fixes #1310. * Added a battle config which allows toggling of the Battleground Queue client feature and also toggles between the modes of scripts. * Added script commands bg_reserve, bg_unbook, and bg_desert. * Removed old custom Battleground scripts. Thanks to @Lemongrass3110, @Locien, @secretdataz, @InusualZ, @Normynator, @Atemo, @iubantot, @admkakaroto, and @noobzter003! --- conf/battle/feature.conf | 4 + conf/msg_conf/map_msg.conf | 5 + db/battleground_db.yml | 174 ++ db/import-tmpl/battleground_db.yml | 52 + doc/script_commands.txt | 47 +- npc/battleground/flavius/flavius01.txt | 77 +- npc/battleground/flavius/flavius02.txt | 77 +- npc/battleground/flavius/flavius_enter.txt | 93 +- npc/battleground/kvm/kvm01.txt | 56 +- npc/battleground/kvm/kvm02.txt | 54 +- npc/battleground/kvm/kvm03.txt | 52 +- npc/battleground/kvm/kvm_enter.txt | 99 +- npc/battleground/kvm/kvm_item_pay.txt | 14 +- npc/battleground/tierra/tierra01.txt | 79 +- npc/battleground/tierra/tierra02.txt | 79 +- npc/battleground/tierra/tierra_enter.txt | 97 +- .../battleground/unofficial/bg_common.txt | 1288 --------------- .../battleground/unofficial/bg_flavius_01.txt | 428 ----- .../battleground/unofficial/bg_flavius_02.txt | 428 ----- .../battleground/unofficial/bg_kvm01.txt | 378 ----- .../battleground/unofficial/bg_kvm02.txt | 378 ----- .../battleground/unofficial/bg_kvm03.txt | 378 ----- .../battleground/unofficial/bg_tierra_01.txt | 476 ------ .../battleground/unofficial/bg_tierra_02.txt | 476 ------ src/common/utilities.hpp | 13 + src/map/battle.cpp | 39 + src/map/battle.hpp | 1 + src/map/battleground.cpp | 1443 +++++++++++++++-- src/map/battleground.hpp | 145 +- src/map/clif.cpp | 206 ++- src/map/clif.hpp | 12 +- src/map/clif_packetdb.hpp | 14 +- src/map/map-server.vcxproj | 1 + src/map/map.cpp | 9 +- src/map/mob.hpp | 2 +- src/map/pc.cpp | 18 +- src/map/pc.hpp | 8 +- src/map/script.cpp | 241 ++- src/map/script_constants.hpp | 11 + src/map/skill.cpp | 3 + src/map/status.cpp | 24 +- src/map/status.hpp | 3 + tools/ci/npc.bat | 7 +- tools/ci/npc.sh | 2 +- 44 files changed, 2687 insertions(+), 4804 deletions(-) create mode 100644 db/battleground_db.yml create mode 100644 db/import-tmpl/battleground_db.yml delete mode 100644 npc/custom/battleground/unofficial/bg_common.txt delete mode 100644 npc/custom/battleground/unofficial/bg_flavius_01.txt delete mode 100644 npc/custom/battleground/unofficial/bg_flavius_02.txt delete mode 100644 npc/custom/battleground/unofficial/bg_kvm01.txt delete mode 100644 npc/custom/battleground/unofficial/bg_kvm02.txt delete mode 100644 npc/custom/battleground/unofficial/bg_kvm03.txt delete mode 100644 npc/custom/battleground/unofficial/bg_tierra_01.txt delete mode 100644 npc/custom/battleground/unofficial/bg_tierra_02.txt diff --git a/conf/battle/feature.conf b/conf/battle/feature.conf index 2747fe5380..a39eb39a81 100644 --- a/conf/battle/feature.conf +++ b/conf/battle/feature.conf @@ -59,6 +59,10 @@ feature.autotrade_sit: 1 // Delay in miliseconds to open vending/buyingsotre after player logged in. feature.autotrade_open_delay: 5000 +// Battlegrounds queue interface. Makes it possible to queue for a battleground anywhere using the battle menu. +// Requires: 2012-04-10aRagexe or later +feature.bgqueue: on + // Roulette (Note 1) // Requires: 2014-10-22bRagexe or later feature.roulette: on diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf index d1b2410cf4..c5cce443c2 100644 --- a/conf/msg_conf/map_msg.conf +++ b/conf/msg_conf/map_msg.conf @@ -353,6 +353,11 @@ // 334: Thirty-Four Castles 334: Total Domination +// Battlegrounds Queue +337: You may not join a battleground queue when you're in a battleground map. +338: You can't apply to a battleground queue due to recently deserting a battleground. Time remaining: %d minutes and %d seconds. +339: You can't apply to a battleground queue for %d seconds due to recently leaving one. + // Templates for @who output 343: Name: %s 344: (%s) diff --git a/db/battleground_db.yml b/db/battleground_db.yml new file mode 100644 index 0000000000..2dbed729ad --- /dev/null +++ b/db/battleground_db.yml @@ -0,0 +1,174 @@ +# This file is a part of rAthena. +# Copyright(C) 2019 rAthena Development Team +# https://rathena.org - https://github.com/rathena +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU 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 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 . +# +########################################################################### +# Battleground Queue Database +########################################################################### +# +# Battleground Queue Settings +# +########################################################################### +# - Id Unique ID for the battleground type. +# Name Name of the battleground. Must be the exact same as in the client for players to be able to join. +# MinPlayers Minimum number of players required on each team. (Default: 1) +# MaxPlayers Maximum number of players on each team. (Default: MAX_BG_MEMBERS / 2) +# MinLevel Minimum level required to join the battleground. (Default: 1) +# MaxLevel Maximum level to join the battleground. (Default: MAX_LEVEL value) +# Deserter Amount of time in seconds a player is marked deserter. (Default: 600) +# StartDelay Amount of time in seconds once a queue is filled before a start message is sent to players. (Default: 30) +# Locations: Battleground location settings. +# - Map The map on which the battleground will be played. +# StartEvent NPC event triggered when the battleground starts. +# TeamA: TeamA settings. +# RespawnX X coordinate for warping on death. +# RespawnY Y coordinate for warping on death. +# DeathEvent NPC event triggered when a player dies. +# QuitEvent NPC event triggered when a player quits. +# Variable Name of BG ID variable used in the battleground script. +# TeamB: TeamB settings. +# RespawnX X coordinate for warping on death. +# RespawnY Y coordinate for warping on death. +# DeathEvent NPC event triggered when a player dies. +# QuitEvent NPC event triggered when a player quits. +# Variable Name of BG ID variable used in the battleground script. +########################################################################### + +Header: + Type: BATTLEGROUND_DB + Version: 1 + +Body: + - Id: 1 + Name: "Tierra Gorge" + MinPlayers: 6 + MinLevel: 80 + Locations: + - Map: "bat_a01" + StartEvent: "start#bat_a01::OnReadyCheck" + TeamA: + RespawnX: 50 + RespawnY: 374 + QuitEvent: "start#bat_a01::OnGuillaumeQuit" + Variable: "$@TierraBG1_id1" + TeamB: + RespawnX: 42 + RespawnY: 16 + QuitEvent: "start#bat_a01::OnCroixQuit" + Variable: "$@TierraBG1_id2" + - Map: "bat_a02" + StartEvent: "start#bat_a02::OnReadyCheck" + TeamA: + RespawnX: 50 + RespawnY: 374 + QuitEvent: "start#bat_a02::OnGuillaumeQuit" + Variable: "$@TierraBG2_id1" + TeamB: + RespawnX: 42 + RespawnY: 16 + QuitEvent: "start#bat_a02::OnCroixQuit" + Variable: "$@TierraBG2_id2" + - Id: 2 + Name: "Flavius" + MinPlayers: 6 + MinLevel: 80 + Locations: + - Map: "bat_b01" + StartEvent: "start#bat_b01::OnReadyCheck" + TeamA: + RespawnX: 10 + RespawnY: 290 + QuitEvent: "start#bat_b01::OnGuillaumeQuit" + Variable: "$@FlaviusBG1_id1" + TeamB: + RespawnX: 390 + RespawnY: 10 + QuitEvent: "start#bat_b01::OnCroixQuit" + Variable: "$@FlaviusBG1_id2" + - Map: "bat_b02" + StartEvent: "start#bat_b02::OnReadyCheck" + TeamA: + RespawnX: 10 + RespawnY: 290 + QuitEvent: "start#bat_b02::OnGuillaumeQuit" + Variable: "$@FlaviusBG2_id1" + TeamB: + RespawnX: 390 + RespawnY: 10 + QuitEvent: "start#bat_b02::OnCroixQuit" + Variable: "$@FlaviusBG2_id2" + - Id: 3 + Name: "KVM (Level 80 and up)" + MinPlayers: 5 + MinLevel: 80 + Locations: + - Map: "bat_c01" + StartEvent: "KvM01_BG::OnStart" + TeamA: + RespawnX: 52 + RespawnY: 129 + DeathEvent: "KvM01_BG::OnGuillaumeDie" + QuitEvent: "KvM01_BG::OnGuillaumeQuit" + Variable: "$@KvM01BG_id1" + TeamB: + RespawnX: 147 + RespawnY: 55 + DeathEvent: "KvM01_BG::OnCroixDie" + QuitEvent: "KvM01_BG::OnCroixQuit" + Variable: "$@KvM01BG_id2" + - Id: 4 + Name: "KVM (Level 60~79)" + MinPlayers: 5 + MinLevel: 60 + MaxLevel: 79 + Locations: + - Map: "bat_c02" + StartEvent: "KvM02_BG::OnStart" + TeamA: + RespawnX: 52 + RespawnY: 129 + DeathEvent: "KvM02_BG::OnGuillaumeDie" + QuitEvent: "KvM02_BG::OnGuillaumeQuit" + Variable: "$@KvM02BG_id1" + TeamB: + RespawnX: 147 + RespawnY: 55 + DeathEvent: "KvM02_BG::OnCroixDie" + QuitEvent: "KvM02_BG::OnCroixQuit" + Variable: "$@KvM02BG_id2" + - Id: 5 + Name: "KVM (Level 59 and below" + MinPlayers: 5 + MaxLevel: 59 + Locations: + - Map: "bat_c03" + StartEvent: "KvM03_BG::OnStart" + TeamA: + RespawnX: 52 + RespawnY: 129 + DeathEvent: "KvM03_BG::OnGuillaumeDie" + QuitEvent: "KvM03_BG::OnGuillaumeQuit" + Variable: "$@KvM03BG_id1" + TeamB: + RespawnX: 147 + RespawnY: 55 + DeathEvent: "KvM03_BG::OnCroixDie" + QuitEvent: "KvM03_BG::OnCroixQuit" + Variable: "$@KvM03BG_id2" + +Footer: + Imports: + - Path: db/import/battleground_db.yml diff --git a/db/import-tmpl/battleground_db.yml b/db/import-tmpl/battleground_db.yml new file mode 100644 index 0000000000..9d7300bdd7 --- /dev/null +++ b/db/import-tmpl/battleground_db.yml @@ -0,0 +1,52 @@ +# This file is a part of rAthena. +# Copyright(C) 2019 rAthena Development Team +# https://rathena.org - https://github.com/rathena +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU 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 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 . +# +########################################################################### +# Battleground Queue Database +########################################################################### +# +# Battleground Queue Settings +# +########################################################################### +# - Id Unique ID for the battleground type. +# Name Name of the battleground. Must be the exact same as in the client for players to be able to join. +# MinPlayers Minimum number of players required on each team. (Default: 1) +# MaxPlayers Maximum number of players on each team. (Default: MAX_BG_MEMBERS / 2) +# MinLevel Minimum level required to join the battleground. (Default: 1) +# MaxLevel Maximum level to join the battleground. (Default: MAX_LEVEL value) +# Deserter Amount of time in seconds a player is marked deserter. (Default: 600) +# StartDelay Amount of time in seconds once a queue is filled before a start message is sent to players. (Default: 30) +# Locations: Battleground location settings. +# - Map The map on which the battleground will be played. +# StartEvent NPC event triggered when the battleground starts. +# TeamA: TeamA settings. +# RespawnX X coordinate for warping on death. +# RespawnY Y coordinate for warping on death. +# DeathEvent NPC event triggered when a player dies. +# QuitEvent NPC event triggered when a player quits. +# Variable Name of BG ID variable used in the battleground script. +# TeamB: TeamB settings. +# RespawnX X coordinate for warping on death. +# RespawnY Y coordinate for warping on death. +# DeathEvent NPC event triggered when a player dies. +# QuitEvent NPC event triggered when a player quits. +# Variable Name of BG ID variable used in the battleground script. +########################################################################### + +Header: + Type: BATTLEGROUND_DB + Version: 1 diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 93ee6d2f62..4d8390dce8 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -9305,7 +9305,8 @@ QMARK_PURPLE - Purple Marker *waitingroom2bg_single(,{"",,{,""}}); Adds the first waiting player from the chat room of the given NPC to an existing battleground group. -The player will also be warped to the default spawn point of the battle group or to the specified coordinates and on the given . +The player will also be warped to the default spawn point of the battle group or to the specified coordinates + and on the given . --------------------------------------- @@ -9349,7 +9350,8 @@ Returns battle group ID on success. Returns 0 on failure. *bg_join(,{"",{,{,}}); -Adds an attached player or if specified to an existing battleground group. The player will also be warped to the default spawn point of the battle group or to the specified coordinates and on the given . +Adds an attached player or if specified to an existing battleground group. The player will also be warped +to the default spawn point of the battle group or to the specified coordinates and on the given . Returns true on success. Returns false on failure. @@ -9357,7 +9359,8 @@ Returns true on success. Returns false on failure. *bg_team_setxy ,,; -Updates the respawn point of the given Battle Group to x,y on the same map. can be retrieved using getcharid(4). +Updates the respawn point of the given Battle Group to x,y on the same map. can be retrieved +using getcharid(4). Example: bg_team_setxy getcharid(4),56,212; @@ -9366,6 +9369,29 @@ Example: --------------------------------------- +*bg_reserve(""); + +Reserves a slot for the given Battleground for the Battleground UI System. + +Note: 'bg_reserve' and 'bg_unbook' prevent the Battlegrounds queue from joining players in an active Battleground. + +--------------------------------------- + +*bg_unbook(""); + +Removes a spot for the given Battleground for the Battleground UI System. + +Note: 'bg_reserve' and 'bg_unbook' prevent the Battlegrounds queue from joining players in an active Battleground. + +--------------------------------------- + +*bg_desert({}); + +Same as 'bg_leave' but slaps the player with a deserter status so they can't enter another queue for the time +defined in battleground_db (10 minutes by default). + +--------------------------------------- + *bg_warp ,"",,; Similar to the 'warp' command. @@ -9469,6 +9495,21 @@ mapflag battleground 2 --------------------------------------- +*bg_info("", ); + +Retrieves data related to given from the database. Requires feature.bgqueue +to be enabled. can be one of the following: + + BG_INFO_ID: Battleground ID. + BG_INFO_REQUIRED_PLAYERS: Required players to start a battleground (per side). + BG_INFO_MAX_PLAYERS: Maximum players allowed in a battleground. + BG_INFO_MIN_LEVEL: Minimum level allowed to join a battleground. + BG_INFO_MAX_LEVEL: Maximum level allowed to join a battleground. + BG_INFO_MAPS: Number of maps in a battleground. Stores an array of map names in @bgmaps[] and a count in @bgmapscount. + BG_INFO_DESERTER_TIME: Amount of time in seconds a player is marked deserter. + +--------------------------------------- + ==================== |10.- Pet commands.| ==================== diff --git a/npc/battleground/flavius/flavius01.txt b/npc/battleground/flavius/flavius01.txt index 9e5e305aa0..af61c09a46 100644 --- a/npc/battleground/flavius/flavius01.txt +++ b/npc/battleground/flavius/flavius01.txt @@ -1,18 +1,12 @@ -//===== rAthena Script ======================================= +//===== rAthena Script ======================================= //= BattleGround System - Flavius -//===== By: ================================================== -//= L0ne_W0lf -//===== Current Version: ===================================== -//= 1.7 -//===== Compatible With: ===================================== -//= rAthena Project -//===== Description: ========================================= +//===== Description: ========================================= //= [Official Conversion] //= Flavius Battleground. //= - Winning Team: 9 badges (11 if VIP) //= - Losing Team: 3 badges (5 if VIP) -//===== Additional Comments: ================================= -//= 1.0 First Version. +//===== Changelogs: ========================================== +//= 1.0 First Version. [L0ne_W0lf] //= 1.1 Fixed pink crystal spawning as blue. [L0ne_W0lf] //= 1.2 Updated 'waitingroom' to support required zeny/lvl. [Kisuka] //= 1.3 Removed MaxLvl check in waitingrooms. Replaced setwall with setcell. @@ -20,6 +14,7 @@ //= 1.5 Added GM management function. [Euphy] //= 1.6 Added VIP features and created a reward function. [Euphy] //= 1.7 Made Crystals immune to attacks until Guardians are defeated. [Cydh/Aleos] +//= 1.8 Added battle_config checks to allow this script to use the new queue interface or the previous method. [Aleos] //============================================================ // Waiting Room NPCs @@ -51,6 +46,8 @@ bat_room,2,151,3 script #bat_b01_timer 844,{ end; OnInit: + if (getbattleflag("feature.bgqueue")) + end; OnEnable: initnpctimer; end; @@ -61,14 +58,21 @@ OnStop: OnTimer1000: stopnpctimer; - initnpctimer; + if (!getbattleflag("feature.bgqueue")) + initnpctimer; set .@chk_bat_a01,getmapusers("bat_b01"); if (.@chk_bat_a01 < 1) { set $@FlaviusBG1, 0; if( $@FlaviusBG1_id1 ) { bg_destroy $@FlaviusBG1_id1; set $@FlaviusBG1_id1, 0; } if( $@FlaviusBG1_id2 ) { bg_destroy $@FlaviusBG1_id2; set $@FlaviusBG1_id2, 0; } - donpcevent "start#bat_b01::OnReadyCheck"; + if (getbattleflag("feature.bgqueue")) { + bg_unbook "bat_b01"; + end; + } else + donpcevent "start#bat_b01::OnReadyCheck"; } + if (getbattleflag("feature.bgqueue")) + initnpctimer; end; } @@ -83,22 +87,26 @@ OnInit: OnReadyCheck: if( $@FlaviusBG1 ) end; - set .@Guillaume, getwaitingroomstate(0,"Lieutenant Ator"); - set .@Croix, getwaitingroomstate(0,"Lieutenant Thelokus"); - if( !.@Guillaume && !.@Croix ) { - donpcevent "#bat_b01_timer::OnStop"; - end; + if (!getbattleflag("feature.bgqueue")) { + set .@Guillaume, getwaitingroomstate(0,"Lieutenant Ator"); + set .@Croix, getwaitingroomstate(0,"Lieutenant Thelokus"); + if( !.@Guillaume && !.@Croix ) { + donpcevent "#bat_b01_timer::OnStop"; + end; + } + if( .@Guillaume < 10 || .@Croix < 10 ) + end; } - if( .@Guillaume < 10 || .@Croix < 10 ) - end; set $@FlaviusBG1, 1; set $@FlaviusBG1_Victory, 0; set $@Croix_ScoreBG1, 0; set $@Guill_ScoreBG1, 0; bg_updatescore "bat_b01",$@Guill_ScoreBG1,$@Croix_ScoreBG1; - donpcevent "Lieutenant Ator::OnEnterBG"; - donpcevent "Lieutenant Thelokus::OnEnterBG"; + if (!getbattleflag("feature.bgqueue")) { + donpcevent "Lieutenant Ator::OnEnterBG"; + donpcevent "Lieutenant Thelokus::OnEnterBG"; + } donpcevent "OBJ#bat_b01_a::OnKill"; donpcevent "OBJ#bat_b01_a::OnEnable"; donpcevent "OBJ#bat_b01_b::OnKill"; @@ -142,7 +150,10 @@ OnReset: OnGuillaumeQuit: OnCroixQuit: - bg_leave; + if (getbattleflag("feature.bgqueue")) + bg_desert; + else + bg_leave; end; OnTimer10000: @@ -405,7 +416,8 @@ bat_b01,10,294,3 script Guillaume Vintenar#b01_a 934,{ callfunc "F_BG_Badge",0,"Guillaume","Flavius"; } bg_leave; - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; end; OnInit: @@ -421,7 +433,8 @@ bat_b01,389,14,3 script Croix Vintenar#b01_b 934,{ callfunc "F_BG_Badge",0,"Croix","Flavius"; } bg_leave; - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; end; OnInit: @@ -579,3 +592,19 @@ bat_b01,1,10,3 script Release all#b01 81,{ } } } + +// BG Queue makes these scripts useless +- script BGQueueInit#flavius01 -1,{ + end; + +OnInit: + if (getbattleflag("feature.bgqueue")) { + unloadnpc "Lieutenant Ator"; + unloadnpc "Lieutenant Thelokus"; + unloadnpc "back_bgroomb01a"; + unloadnpc "back_bgroomb01b"; + unloadnpc "A_CODE#bat_b01"; + unloadnpc "B_CODE#bat_b01"; + } + end; +} diff --git a/npc/battleground/flavius/flavius02.txt b/npc/battleground/flavius/flavius02.txt index 09988753e2..29ffe62d3a 100644 --- a/npc/battleground/flavius/flavius02.txt +++ b/npc/battleground/flavius/flavius02.txt @@ -1,18 +1,12 @@ -//===== rAthena Script ======================================= +//===== rAthena Script ======================================= //= BattleGround System - Flavius Second -//===== By: ================================================== -//= L0ne_W0lf -//===== Current Version: ===================================== -//= 1.8 -//===== Compatible With: ===================================== -//= rAthena Project -//===== Description: ========================================= +//===== Description: ========================================= //= [Official Conversion] //= Flavius Battleground. //= - Winning Team: 9 badges (11 if VIP) //= - Losing Team: 3 badges (5 if VIP) -//===== Additional Comments: ================================= -//= 1.0 First Version. +//===== Changelogs: ========================================== +//= 1.0 First Version. [L0ne_W0lf] //= 1.1 Fixed NPCs being called for waiting rooms. (bugreport:4395) //= 1.2 Fixed pink crystal spawning as blue. [L0ne_W0lf] //= 1.3 Updated 'waitingroom' to support required zeny/lvl. [Kisuka] @@ -21,6 +15,7 @@ //= 1.6 Added GM management function. [Euphy] //= 1.7 Added VIP features and created a reward function. [Euphy] //= 1.8 Made Crystals immune to attacks until Guardians are defeated. [Cydh/Aleos] +//= 1.9 Added battle_config checks to allow this script to use the new queue interface or the previous method. [Aleos] //============================================================ // Waiting Room NPCs @@ -52,6 +47,8 @@ bat_room,2,151,3 script #bat_b02_timer 844,{ end; OnInit: + if (getbattleflag("feature.bgqueue")) + end; OnEnable: initnpctimer; end; @@ -62,14 +59,21 @@ OnStop: OnTimer1000: stopnpctimer; - initnpctimer; + if (!getbattleflag("feature.bgqueue")) + initnpctimer; set .@chk_bat_a01,getmapusers("bat_b02"); if (.@chk_bat_a01 < 1) { set $@FlaviusBG2, 0; if( $@FlaviusBG2_id1 ) { bg_destroy $@FlaviusBG2_id1; set $@FlaviusBG2_id1, 0; } if( $@FlaviusBG2_id2 ) { bg_destroy $@FlaviusBG2_id2; set $@FlaviusBG2_id2, 0; } - donpcevent "start#bat_b02::OnReadyCheck"; + if (getbattleflag("feature.bgqueue")) { + bg_unbook "bat_b01"; + end; + } else + donpcevent "start#bat_b01::OnReadyCheck"; } + if (getbattleflag("feature.bgqueue")) + initnpctimer; end; } @@ -84,22 +88,26 @@ OnInit: OnReadyCheck: if( $@FlaviusBG2 ) end; - set .@Guillaume, getwaitingroomstate(0,"Lieutenant Huvas"); - set .@Croix, getwaitingroomstate(0,"Lieutenant Yukon"); - if( !.@Guillaume && !.@Croix ) { - donpcevent "#bat_b02_timer::OnStop"; - end; + if (!getbattleflag("feature.bgqueue")) { + set .@Guillaume, getwaitingroomstate(0,"Lieutenant Huvas"); + set .@Croix, getwaitingroomstate(0,"Lieutenant Yukon"); + if( !.@Guillaume && !.@Croix ) { + donpcevent "#bat_b02_timer::OnStop"; + end; + } + if( .@Guillaume < 10 || .@Croix < 10 ) + end; } - if( .@Guillaume < 10 || .@Croix < 10 ) - end; set $@FlaviusBG2, 1; set $@FlaviusBG2_Victory, 0; set $@Croix_ScoreBG2, 0; set $@Guill_ScoreBG2, 0; bg_updatescore "bat_b02",$@Guill_ScoreBG2,$@Croix_ScoreBG2; - donpcevent "Lieutenant Huvas::OnEnterBG"; - donpcevent "Lieutenant Yukon::OnEnterBG"; + if (!getbattleflag("feature.bgqueue")) { + donpcevent "Lieutenant Huvas::OnEnterBG"; + donpcevent "Lieutenant Yukon::OnEnterBG"; + } donpcevent "OBJ#bat_b02_a::OnKill"; donpcevent "OBJ#bat_b02_a::OnEnable"; donpcevent "OBJ#bat_b02_b::OnKill"; @@ -143,7 +151,10 @@ OnReset: OnGuillaumeQuit: OnCroixQuit: - bg_leave; + if (getbattleflag("feature.bgqueue")) + bg_desert; + else + bg_leave; end; OnTimer10000: @@ -406,7 +417,8 @@ bat_b02,10,294,3 script Guillaume Vintenar#b02_a 934,{ callfunc "F_BG_Badge",0,"Guillaume","Flavius"; } bg_leave; - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; end; OnInit: @@ -422,7 +434,8 @@ bat_b02,389,14,3 script Croix Vintenar#b02_b 934,{ callfunc "F_BG_Badge",0,"Croix","Flavius"; } bg_leave; - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; end; OnInit: @@ -580,3 +593,19 @@ bat_b02,1,10,3 script Release all#b02 81,{ } } } + +// BG Queue makes these scripts useless +- script BGQueueInit#flavius02 -1,{ + end; + +OnInit: + if (getbattleflag("feature.bgqueue")) { + unloadnpc "Lieutenant Huvas"; + unloadnpc "Lieutenant Yukon"; + unloadnpc "back_bgroomb02a"; + unloadnpc "back_bgroomb02b"; + unloadnpc "A_CODE#bat_b02"; + unloadnpc "B_CODE#bat_b02"; + } + end; +} diff --git a/npc/battleground/flavius/flavius_enter.txt b/npc/battleground/flavius/flavius_enter.txt index 48a0e5fecb..12f4edbaac 100644 --- a/npc/battleground/flavius/flavius_enter.txt +++ b/npc/battleground/flavius/flavius_enter.txt @@ -1,21 +1,18 @@ -//===== rAthena Script ======================================= +//===== rAthena Script ======================================= //= BattleGround System - Flavius Entrance NPCs -//===== By: ================================================== -//= L0ne_W0lf -//===== Current Version: ===================================== -//= 1.0 -//===== Compatible With: ===================================== -//= rAthena Project -//===== Description: ========================================= +//===== Description: ========================================= //= [Official Conversion] //= Flavius Battleground Entrance NPCs -//===== Additional Comments: ================================= -//= 1.0 First Version. +//===== Changelogs: ========================================== +//= 1.0 First Version. [L0ne_W0lf] +//= 1.1 Added battle_config checks to allow this script to use the new queue interface or the previous method. [Aleos] //============================================================ // Flavius Officer - Guillaume //============================================================ bat_room,133,178,5 script Flavius Officer#01a 418,{ + if (getbattleflag("feature.bgqueue")) + end; if (checkweight(1201,1) == 0) { mes "- Wait a minute !! -"; mes "- Currently you're carrying -"; @@ -83,6 +80,8 @@ bat_room,133,178,5 script Flavius Officer#01a 418,{ } bat_room,133,121,1 script Flavius Officer#01b 414,{ + if (getbattleflag("feature.bgqueue")) + end; if (checkweight(1201,1) == 0) { mes "- Wait a minute !! -"; mes "- Currently you're carrying -"; @@ -163,35 +162,22 @@ bat_room,135,178,5 script Guillaume Knight#3 417,{ mes "The crystals are immune to every type of skill; your physical attacks are the only choice for destroying your enemy's crystal."; next; mes "[Guillaume Knight]"; - mes "Please remember: when you join a battle, you will be receiving a token which indicates the set duration for which you cannot participate in the same type of battle."; - mes "You may check the duration by pressing the Alt+U keys."; + if (getbattleflag("feature.bgqueue")) + mes "If you are ready, start by clicking the ^0000FFbattle button from the interface^000000."; + else { + mes "Please remember: when you join a battle, you will be receiving a token which indicates the set duration for which you cannot participate in the same type of battle."; + mes "You may check the duration by pressing the Alt+U keys."; + } next; mes "[Guillaume Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; + if (getbattleflag("feature.bgqueue")) + mes "Please bear in mind once you cancel, ^0000FFyou may not reapply for 1 minute^000000!"; + else + mes "Are you ready for battle? Then apply with the recruiter next to me!"; close; } -bat_room,151,178,5 script Guillaume Knight#4 417,{ - mes "[Guillaume Knight]"; - mes "The objective of the Flavius Battle is to score 2 points before your enemy by destroying their crystal."; - next; - mes "[Guillaume Knight]"; - mes "The crystals for both armies are protected by special barricades that cannot be destroyed by direct attacks."; - next; - mes "[Guillaume Knight]"; - mes "But they can be removed by destroying the Guardians that protect the enemy army base."; - next; - mes "[Guillaume Knight]"; - mes "The crystals are immune to every type of skill; your physical attacks are the only choice for destroying your enemy's crystal."; - next; - mes "[Guillaume Knight]"; - mes "Please remember: when you join a battle, you will be receiving a token which indicates the set duration for which you cannot participate in the same type of battle."; - mes "You may check the duration by pressing the Alt+U keys."; - next; - mes "[Guillaume Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} +bat_room,151,178,5 duplicate(Guillaume Knight#3) Guillaume Knight#4 417 bat_room,135,121,1 script Croix Knight#3 413,{ mes "[Croix Knight]"; @@ -207,39 +193,28 @@ bat_room,135,121,1 script Croix Knight#3 413,{ mes "The crystals are immune to every type of skill; your physical attacks are the only choice for destroying your enemy's crystal."; next; mes "[Croix Knight]"; - mes "Please remember: when you join a battle, you will be receiving a token which indicates the set duration for which you cannot participate in the same type of battle."; - mes "You may check the duration by pressing the Alt+U keys."; + if (getbattleflag("feature.bgqueue")) + mes "If you are ready, start by clicking the ^0000FFbattle button from the interface^000000."; + else { + mes "Please remember: when you join a battle, you will be receiving a token which indicates the set duration for which you cannot participate in the same type of battle."; + mes "You may check the duration by pressing the Alt+U keys."; + } next; mes "[Croix Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; + if (getbattleflag("feature.bgqueue")) + mes "Please bear in mind once you cancel, ^0000FFyou may not reapply for 1 minute^000000!"; + else + mes "Are you ready for battle? Then apply with the recruiter next to me!"; close; } -bat_room,151,121,1 script Croix Knight#4 413,{ - mes "[Croix Knight]"; - mes "The objective of the Flavius Battle is to score 2 points before your enemy by destroying their crystal."; - next; - mes "[Croix Knight]"; - mes "The crystals for both armies are protected by special barricades that cannot be destroyed by direct attacks."; - next; - mes "[Croix Knight]"; - mes "But they can be removed by destroying the Guardians that protect the enemy army base."; - next; - mes "[Croix Knight]"; - mes "The crystals are immune to every type of skill; your physical attacks are the only choice for destroying your enemy's crystal."; - next; - mes "[Croix Knight]"; - mes "Please remember: when you join a battle, you will be receiving a token which indicates the set duration for which you cannot participate in the same type of battle."; - mes "You may check the duration by pressing the Alt+U keys."; - next; - mes "[Croix Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} +bat_room,151,121,1 duplicate(Croix Knight#3) Croix Knight#4 413 // Flavius Officer - Croix //============================================================ bat_room,148,178,5 script Flavius Officer#02a 418,{ + if (getbattleflag("feature.bgqueue")) + end; if (checkweight(1201,1) == 0) { mes "- Wait a minute !! -"; mes "- Currently you're carrying -"; @@ -307,6 +282,8 @@ bat_room,148,178,5 script Flavius Officer#02a 418,{ } bat_room,148,121,1 script Flavius Officer#02b 414,{ + if (getbattleflag("feature.bgqueue")) + end; if (checkweight(1201,1) == 0) { mes "- Wait a minute !! -"; mes "- Currently you're carrying -"; diff --git a/npc/battleground/kvm/kvm01.txt b/npc/battleground/kvm/kvm01.txt index 536b409bd8..0341aa465d 100644 --- a/npc/battleground/kvm/kvm01.txt +++ b/npc/battleground/kvm/kvm01.txt @@ -11,7 +11,8 @@ //= 1.2 Upated some announces and dialogs from iRO. //= Changed how the scoreboard works slightly. //= Removed the areapercentheals, and minor things. -//============================================================s +//= 1.3 Added battle_config checks to allow this script to use the new queue interface or the previous method. [Aleos] +//============================================================ // Waiting Room NPCs //============================================================ @@ -81,7 +82,8 @@ OnDisable: end; OnTouch: set Bat_Team,1; - setquest 6025; + if (!getbattleflag("feature.bgqueue")) + setquest 6025; end; } @@ -98,7 +100,8 @@ OnDisable: end; OnTouch: set Bat_Team,2; - setquest 6025; + if (!getbattleflag("feature.bgqueue")) + setquest 6025; end; } @@ -117,7 +120,10 @@ OnInit: end; OnGuillaumeQuit: - //set BG_Delay_Tick, gettimetick(2) + 1200; + if (getbattleflag("feature.bgqueue")) + bg_desert; +// else +// set BG_Delay_Tick, gettimetick(2) + 1200; OnGuillaumeDie: if( $@KvM01BG == 2 ) { @@ -132,7 +138,10 @@ OnGuillaumeDie: end; OnCroixQuit: - //set BG_Delay_Tick, gettimetick(2) + 1200; + if (getbattleflag("feature.bgqueue")) + bg_desert; +// else +// set BG_Delay_Tick, gettimetick(2) + 1200; OnCroixDie: if( $@KvM01BG == 2 ) { @@ -204,14 +213,16 @@ OnTimer61000: // Team Members set .Guillaume_Count, bg_get_data($@KvM01BG_id1, 0); set .Croix_Count, bg_get_data($@KvM01BG_id2, 0); - if( .Guillaume_Count < 5 || .Croix_Count < 5 ) - { - set $@KvM01BG_Victory, 3; - set $@KvM01BG, 3; - mapannounce "bat_c01","There are not enough players to start the battle",1,0x696969; - stopnpctimer; - donpcevent "KvM01_BG::OnStop"; - end; + + if (!getbattleflag("feature.bgqueue")) { + if (.Guillaume_Count < 5 || .Croix_Count < 5) { + set $@KvM01BG_Victory, 3; + set $@KvM01BG, 3; + mapannounce "bat_c01","There are not enough players to start the battle",1,0x696969; + stopnpctimer; + donpcevent "KvM01_BG::OnStop"; + end; + } } set $@KvM01BG, 2; // Playing bg_warp $@KvM01BG_id1,"bat_c01",61,120; @@ -316,6 +327,8 @@ OnTimer60000: set $@KvM01BG_Victory, 0; if( $@KvM01BG_id1 ) { bg_destroy $@KvM01BG_id1; set $@KvM01BG_id1, 0; } if( $@KvM01BG_id2 ) { bg_destroy $@KvM01BG_id2; set $@KvM01BG_id2, 0; } + if (getbattleflag("feature.bgqueue")) + bg_unbook "bat_c01"; disablenpc "KVM Officer#KVM01A"; disablenpc "KVM Officer#KVM01B"; mapwarp "bat_c01","bat_room",154,150; @@ -361,8 +374,23 @@ bat_c01,51,130,5 script KVM Officer#KVM01A 419,{ } bg_leave; set Bat_Team,0; - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; } end; } bat_c01,148,53,1 duplicate(KVM Officer#KVM01A) KVM Officer#KVM01B 415 + +// BG Queue makes these scripts useless +- script BGQueueInit#kvm01 -1,{ + end; + +OnInit: + if (getbattleflag("feature.bgqueue")) { + unloadnpc "KvM01R_Guillaume"; + unloadnpc "KvM01R_Croix"; + unloadnpc "#kvm801"; + unloadnpc "#kvm802"; + } + end; +} diff --git a/npc/battleground/kvm/kvm02.txt b/npc/battleground/kvm/kvm02.txt index 018b4b3b9e..1d90b7d80c 100644 --- a/npc/battleground/kvm/kvm02.txt +++ b/npc/battleground/kvm/kvm02.txt @@ -13,6 +13,7 @@ //= Removed the areapercentheals, and minor things. //= 1.3 Fixed wrong names for disablenpc/enablenpc. [Ai4rei] //= Fixed points in text and actual points differing. +//= 1.4 Added battle_config checks to allow this script to use the new queue interface or the previous method. [Aleos] //============================================================ // Waiting Room NPCs @@ -81,7 +82,8 @@ OnDisable: end; OnTouch: set Bat_Team,1; - setquest 6025; + if (!getbattleflag("feature.bgqueue")) + setquest 6025; end; } @@ -98,7 +100,8 @@ OnDisable: end; OnTouch: set Bat_Team,2; - setquest 6025; + if (!getbattleflag("feature.bgqueue")) + setquest 6025; end; } @@ -117,7 +120,10 @@ OnInit: end; OnGuillaumeQuit: - //set BG_Delay_Tick, gettimetick(2) + 1200; + if (getbattleflag("feature.bgqueue")) + bg_desert; +// else +// set BG_Delay_Tick, gettimetick(2) + 1200; OnGuillaumeDie: if( $@KvM02BG == 2 ) { @@ -132,7 +138,10 @@ OnGuillaumeDie: end; OnCroixQuit: - //set BG_Delay_Tick, gettimetick(2) + 1200; + if (getbattleflag("feature.bgqueue")) + bg_desert; +// else +// set BG_Delay_Tick, gettimetick(2) + 1200; OnCroixDie: if( $@KvM02BG == 2 ) { @@ -204,14 +213,16 @@ OnTimer61000: // Team Members set .Guillaume_Count, bg_get_data($@KvM02BG_id1, 0); set .Croix_Count, bg_get_data($@KvM02BG_id2, 0); - if( .Guillaume_Count < 5 || .Croix_Count < 5 ) - { - set $@KvM02BG_Victory, 3; - set $@KvM02BG, 3; - mapannounce "bat_c02","There are not enough players to start the battle",1,0x808080; - stopnpctimer; - donpcevent "KvM02_BG::OnStop"; - end; + + if (!getbattleflag("feature.bgqueue")) { + if (.Guillaume_Count < 5 || .Croix_Count < 5) { + set $@KvM02BG_Victory, 3; + set $@KvM02BG, 3; + mapannounce "bat_c02","There are not enough players to start the battle",1,0x808080; + stopnpctimer; + donpcevent "KvM02_BG::OnStop"; + end; + } } set $@KvM02BG, 2; // Playing bg_warp $@KvM02BG_id1,"bat_c02",62,119; @@ -316,6 +327,8 @@ OnTimer60000: set $@KvM02BG_Victory, 0; if( $@KvM02BG_id1 ) { bg_destroy $@KvM02BG_id1; set $@KvM02BG_id1, 0; } if( $@KvM02BG_id2 ) { bg_destroy $@KvM02BG_id2; set $@KvM02BG_id2, 0; } + if (getbattleflag("feature.bgqueue")) + bg_unbook "bat_c02"; disablenpc "KVM Officer#KVM02A"; disablenpc "KVM Officer#KVM02B"; mapwarp "bat_c02","bat_room",154,150; @@ -360,8 +373,23 @@ bat_c02,51,130,5 script KVM Officer#KVM02A 419,{ } bg_leave; set Bat_Team,0; - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; end; } } bat_c02,148,53,1 duplicate(KVM Officer#KVM02A) KVM Officer#KVM02B 415 + +// BG Queue makes these scripts useless +- script BGQueueInit#kvm02 -1,{ + end; + +OnInit: + if (getbattleflag("feature.bgqueue")) { + unloadnpc "KvM02R_Guillaume"; + unloadnpc "KvM02R_Croix"; + unloadnpc "#kvm601"; + unloadnpc "#kvm602"; + } + end; +} diff --git a/npc/battleground/kvm/kvm03.txt b/npc/battleground/kvm/kvm03.txt index 7793ca0106..ea6bfe80f1 100644 --- a/npc/battleground/kvm/kvm03.txt +++ b/npc/battleground/kvm/kvm03.txt @@ -12,6 +12,7 @@ //= Changed how the scoreboard works slightly. //= Removed the areapercentheals, and minor things. //= 1.3 Fixed wrong names for disablenpc/enablenpc. [Ai4rei] +//= 1.4 Added battle_config checks to allow this script to use the new queue interface or the previous method. [Aleos] //============================================================ // Waiting Room NPCs @@ -81,7 +82,8 @@ OnDisable: end; OnTouch: set Bat_Team,1; - setquest 6025; + if (!getbattleflag("feature.bgqueue")) + setquest 6025; end; } @@ -98,7 +100,8 @@ OnDisable: end; OnTouch: set Bat_Team,2; - setquest 6025; + if (!getbattleflag("feature.bgqueue")) + setquest 6025; end; } @@ -117,7 +120,10 @@ OnInit: end; OnGuillaumeQuit: - //set BG_Delay_Tick, gettimetick(2) + 1200; + if (getbattleflag("feature.bgqueue")) + bg_desert; +// else +// set BG_Delay_Tick, gettimetick(2) + 1200; OnGuillaumeDie: if( $@KvM03BG == 2 ) { set .Guillaume_Count, .Guillaume_Count - 1; @@ -132,7 +138,10 @@ OnGuillaumeDie: end; OnCroixQuit: - //set BG_Delay_Tick, gettimetick(2) + 1200; + if (getbattleflag("feature.bgqueue")) + bg_desert; +// else +// set BG_Delay_Tick, gettimetick(2) + 1200; OnCroixDie: if( $@KvM03BG == 2 ) { set .Croix_Count, .Croix_Count - 1; @@ -204,14 +213,16 @@ OnTimer61000: // Team Members set .Guillaume_Count, bg_get_data($@KvM03BG_id1, 0); set .Croix_Count, bg_get_data($@KvM03BG_id2, 0); - if( .Guillaume_Count < 5 || .Croix_Count < 5 ) - { - set $@KvM03BG_Victory, 3; - set $@KvM03BG, 3; - mapannounce "bat_c03","There are not enough players to start the battle",1,0xC0C0C0; - stopnpctimer; - donpcevent "KvM03_BG::OnStop"; - end; + + if (!getbattleflag("feature.bgqueue")) { + if (.Guillaume_Count < 5 || .Croix_Count < 5) { + set $@KvM03BG_Victory, 3; + set $@KvM03BG, 3; + mapannounce "bat_c03","There are not enough players to start the battle",1,0xC0C0C0; + stopnpctimer; + donpcevent "KvM03_BG::OnStop"; + end; + } } set $@KvM03BG, 2; // Playing bg_warp $@KvM03BG_id1,"bat_c03",62,119; @@ -316,6 +327,8 @@ OnTimer60000: set $@KvM03BG_Victory, 0; if( $@KvM03BG_id1 ) { bg_destroy $@KvM03BG_id1; set $@KvM03BG_id1, 0; } if( $@KvM03BG_id2 ) { bg_destroy $@KvM03BG_id2; set $@KvM03BG_id2, 0; } + if (getbattleflag("feature.bgqueue")) + bg_unbook "bat_c03"; disablenpc "KVM Officer#KVM03A"; disablenpc "KVM Officer#KVM03B"; mapwarp "bat_c03","bat_room",154,150; @@ -361,8 +374,23 @@ bat_c03,51,130,5 script KVM Officer#KVM03A 419,{ } bg_leave; set Bat_Team,0; + if (!getbattleflag("feature.bgqueue")) warp "bat_room",154,150; } end; } bat_c03,148,53,1 duplicate(KVM Officer#KVM03A) KVM Officer#KVM03B 415 + +// BG Queue makes these scripts useless +- script BGQueueInit#kvm03 -1,{ + end; + +OnInit: + if (getbattleflag("feature.bgqueue")) { + unloadnpc "KvM03R_Guillaume"; + unloadnpc "KvM03R_Croix"; + unloadnpc "#kvm701"; + unloadnpc "#kvm702"; + } + end; +} diff --git a/npc/battleground/kvm/kvm_enter.txt b/npc/battleground/kvm/kvm_enter.txt index 7e92d197ad..4059e176cb 100644 --- a/npc/battleground/kvm/kvm_enter.txt +++ b/npc/battleground/kvm/kvm_enter.txt @@ -1,25 +1,22 @@ -//===== rAthena Script ======================================= +//===== rAthena Script ======================================= //= BattleGround System - KvM Entrance NPCs -//===== By: ================================================== -//= L0ne_W0lf -//===== Current Version: ===================================== -//= 1.1 -//===== Compatible With: ===================================== -//= rAthena Project -//===== Description: ========================================= +//===== Description: ========================================= //= [Official Conversion] //= Kreiger Von Midgard Battleground Entrance NPCs //= Original NPCs scrapped from bg_common. -//===== Additional Comments: ================================= -//= 1.0 First Version. +//===== Changelogs: ========================================== +//= 1.0 First Version. [L0ne_W0lf] //= 1.1 Corrected some typos, and shifted messages around. //= Corrected iRO style quest log entries, however it's //= advisable that you not use them, as they conflict. +//= 1.2 Added battle_config checks to allow this script to use the new queue interface or the previous method. [Aleos] //============================================================ // KvM Officer - Guillaume //============================================================ bat_room,164,178,5 script KVM Mercenary Officer#1 418,{ + if (getbattleflag("feature.bgqueue")) + end; /* set .@kvm,checkquest(6026,PLAYTIME); if ((.@kvm == 0) || (.@kvm == 1)) { @@ -67,8 +64,12 @@ bat_room,167,178,5 script Guillaume Knight#kvm 417,{ switch(select("Apply for KVM.:What is KVM?:How do I participate in KVM?:I want to know my Kreiger Points.")) { case 1: mes "[Guillaume Knight]"; - mes "Applications are not available yet."; - mes "To apply, you need to go to a KVM Mercenary Officer."; + if (getbattleflag("feature.bgqueue")) + mes "If you are ready for battle, click the ^0000FFbattle button from the interface^000000 to apply for KVM battle!"; + else { + mes "Applications are not available yet."; + mes "To apply, you need to go to a KVM Mercenary Officer."; + } close; case 2: mes "[Guillaume Knight]"; @@ -93,21 +94,33 @@ bat_room,167,178,5 script Guillaume Knight#kvm 417,{ close; case 3: mes "[Guillaume Knight]"; - mes "Basically, KVM is a 5 on 5 battle."; - mes "First, you apply with a KVM receptionist, in a group or individually."; + if (getbattleflag("feature.bgqueue")) { + mes "Basically, KVM is a 3 on 3 battle."; + mes "Apply by clicking on the ^0000FFbattle button from the interface^000000, as a group or individually."; + } else { + mes "Basically, KVM is a 5 on 5 battle."; + mes "First, you apply with a KVM receptionist, in a group or individually."; + } next; mes "[Guillaume Knight]"; - mes "Group applications are for when you intend to enter the KVM with your party members,"; + if (getbattleflag("feature.bgqueue")) + mes "Group applications are for when you intend to enter the KVM with your party or guild members,"; + else + mes "Group applications are for when you intend to enter the KVM with your party members,"; mes "and a personal application is for when you intend to enter the KVM individually."; next; mes "[Guillaume Knight]"; - mes "Please apply with a KVM officer, and he will contact you later when you are in Prontera."; - next; - mes "[Guillaume Knight]"; - mes "Then you enter and follow the instructions in the battlefield."; - next; - mes "[Guillaume Knight]"; - mes "However, please be advised that unless you are in the KVM office, he cannot contact you."; + if (getbattleflag("feature.bgqueue")) + mes "Please be noted, once you cancel you ^0000FFcannot apply again for 1 minute^000000."; + else { + mes "Please apply with a KVM officer, and he will contact you later when you are in Prontera."; + next; + mes "[Guillaume Knight]"; + mes "Then you enter and follow the instructions in the battlefield."; + next; + mes "[Guillaume Knight]"; + mes "However, please be advised that unless you are in the KVM office, he cannot contact you."; + } close; case 4: mes "[Guillaume Knight]"; @@ -120,6 +133,8 @@ bat_room,167,178,5 script Guillaume Knight#kvm 417,{ // KvM Officer - Croix //============================================================ bat_room,164,121,1 script KVM Mercenary Officer#2 414,{ + if (getbattleflag("feature.bgqueue")) + end; /* set .@kvm,checkquest(6025,PLAYTIME); if ((.@kvm == 0) || (.@kvm == 1)) { @@ -167,8 +182,12 @@ bat_room,167,121,1 script Croix Knight#kvm 413,{ switch(select("Apply for KVM.:What is KVM?:How do I participate in KVM?:I want to know my Kreiger Points.")) { case 1: mes "[Croix Knight]"; - mes "Applications are not available yet."; - mes "To apply, you need to go to a KVM Mercenary Officer."; + if (getbattleflag("feature.bgqueue")) + mes "If you are ready for battle, click the ^0000FFbattle button from the interface^000000 to apply for KVM battle!"; + else { + mes "Applications are not available yet."; + mes "To apply, you need to go to a KVM Mercenary Officer."; + } close; case 2: mes "[Croix Knight]"; @@ -193,21 +212,33 @@ bat_room,167,121,1 script Croix Knight#kvm 413,{ close; case 3: mes "[Croix Knight]"; - mes "Basically, KVM is a 5 on 5 battle."; - mes "First, you apply with a KVM receptionist, in a group or individually."; + if (getbattleflag("feature.bgqueue")) { + mes "Basically, KVM is a 3 on 3 battle."; + mes "Apply by clicking on the ^0000FFbattle button from the interface^000000, as a group or individually."; + } else { + mes "Basically, KVM is a 5 on 5 battle."; + mes "First, you apply with a KVM receptionist, in a group or individually."; + } next; mes "[Croix Knight]"; - mes "Group applications are for when you intend to enter the KVM with your party members,"; + if (getbattleflag("feature.bgqueue")) + mes "Group applications are for when you intend to enter the KVM with your party or guild members,"; + else + mes "Group applications are for when you intend to enter the KVM with your party members,"; mes "and a personal application is for when you intend to enter the KVM individually."; next; mes "[Croix Knight]"; - mes "Please apply with a KVM officer, and he will contact you later when you are in Prontera."; - next; - mes "[Croix Knight]"; - mes "Then you enter and follow the instructions in the battlefield."; - next; - mes "[Croix Knight]"; - mes "However, please be advised that unless you are in the KVM office, he cannot contact you."; + if (getbattleflag("feature.bgqueue")) + mes "Please be noted, once you cancel you ^0000FFcannot apply again for 1 minute^000000."; + else { + mes "Please apply with a KVM officer, and he will contact you later when you are in Prontera."; + next; + mes "[Croix Knight]"; + mes "Then you enter and follow the instructions in the battlefield."; + next; + mes "[Croix Knight]"; + mes "However, please be advised that unless you are in the KVM office, he cannot contact you."; + } close; case 4: mes "[Croix Knight]"; diff --git a/npc/battleground/kvm/kvm_item_pay.txt b/npc/battleground/kvm/kvm_item_pay.txt index 7b67863d67..ec2d1cfe44 100644 --- a/npc/battleground/kvm/kvm_item_pay.txt +++ b/npc/battleground/kvm/kvm_item_pay.txt @@ -1,12 +1,6 @@ -//===== rAthena Script ======================================= +//===== rAthena Script ======================================= //= BattleGround System - KvM Item Dealer -//===== By: ================================================== -//= L0ne_W0lf -//===== Current Version: ===================================== -//= 1.0 -//===== Compatible With: ===================================== -//= rAthena Project -//===== Description: ========================================= +//===== Description: ========================================= //= [Official Conversion] //= Kreiger Von Midgard Battleground Point redemption NPC //= * NOTE * @@ -14,8 +8,8 @@ //= keep track of points. This NPC when talked to will //= convert already-given tokens and convert them to points. //= under the player variable kvm_point. -//===== Additional Comments: ================================= -//= 1.0 First Version. +//===== Changelogs: ========================================== +//= 1.0 First Version. [L0ne_W0lf] //============================================================ bat_room,151,144,3 script KVM Logistic Officer#a 734,{ diff --git a/npc/battleground/tierra/tierra01.txt b/npc/battleground/tierra/tierra01.txt index 5ee7bbeae4..dd0282789e 100644 --- a/npc/battleground/tierra/tierra01.txt +++ b/npc/battleground/tierra/tierra01.txt @@ -1,24 +1,19 @@ -//===== rAthena Script ======================================= +//===== rAthena Script ======================================= //= BattleGround System - Tierra Gorge -//===== By: ================================================== -//= L0ne_W0lf -//===== Current Version: ===================================== -//= 1.6 -//===== Compatible With: ===================================== -//= rAthena Project -//===== Description: ========================================= +//===== Description: ========================================= //= [Official Conversion] //= Tierra Gorge Battleground. //= - Winning Team: 3 badges (5 if VIP) //= - Losing Team: 1 badge (3 if VIP) -//===== Additional Comments: ================================= -//= 1.0 First Version. +//===== Changelogs: ========================================== +//= 1.0 First Version. [L0ne_W0lf] //= 1.1 Corrected setwalls for barricades. [L0ne_W0lf] //= 1.2 Updated 'waitingroom' to support required zeny/lvl. [Kisuka] //= 1.3 Removed MaxLvl check in waitingrooms. //= 1.4 Label standardization. [Euphy] //= 1.5 Added GM management function. [Euphy] //= 1.6 Added VIP features and created a reward function. [Euphy] +//= 1.7 Added battle_config checks to allow this script to use the new queue interface or the previous method. [Aleos] //============================================================ // Waiting Room NPCs @@ -51,6 +46,8 @@ bat_room,1,151,3 script #bat_a01_timer 844,{ end; OnInit: + if (getbattleflag("feature.bgqueue")) + end; OnEnable: initnpctimer; end; @@ -61,14 +58,21 @@ OnStop: OnTimer1000: stopnpctimer; - initnpctimer; + if (!getbattleflag("feature.bgqueue")) + initnpctimer; set .@chk_bat_a01,getmapusers("bat_a01"); if (.@chk_bat_a01 < 1) { set $@TierraBG1,0; set $@TierraBG1_Victory, 0; if( $@TierraBG1_id1 ) { bg_destroy $@TierraBG1_id1; set $@TierraBG1_id1, 0; } if( $@TierraBG1_id2 ) { bg_destroy $@TierraBG1_id2; set $@TierraBG1_id2, 0; } - donpcevent "start#bat_a01::OnReadyCheck"; + if (getbattleflag("feature.bgqueue")) { + bg_unbook "bat_a01"; + end; + } else + donpcevent "start#bat_a01::OnReadyCheck"; } + if (getbattleflag("feature.bgqueue")) + initnpctimer; end; } @@ -124,23 +128,30 @@ OnEnable: OnGuillaumeQuit: OnCroixQuit: - bg_leave; + if (getbattleflag("feature.bgqueue")) + bg_desert; + else + bg_leave; end; OnReadyCheck: if( $@TierraBG1 ) end; - set .@Guillaume, getwaitingroomstate(0,"Lieutenant Kalos"); - set .@Croix, getwaitingroomstate(0,"Lieutenant Eyor"); - if( !.@Guillaume && !.@Croix ) { - donpcevent "#bat_a01_timer::OnStop"; - end; + if (!getbattleflag("feature.bgqueue")) { + set .@Guillaume, getwaitingroomstate(0,"Lieutenant Kalos"); + set .@Croix, getwaitingroomstate(0,"Lieutenant Eyor"); + if( !.@Guillaume && !.@Croix ) { + donpcevent "#bat_a01_timer::OnStop"; + end; + } + else if( .@Guillaume < 10 || .@Croix < 10 ) + end; } - else if( .@Guillaume < 10 || .@Croix < 10 ) - end; set $@TierraBG1,1; - donpcevent "Lieutenant Kalos::OnEnterBG"; - donpcevent "Lieutenant Eyor::OnEnterBG"; + if (!getbattleflag("feature.bgqueue")) { + donpcevent "Lieutenant Kalos::OnEnterBG"; + donpcevent "Lieutenant Eyor::OnEnterBG"; + } donpcevent "start#bat_a01::OnEnable"; bg_warp $@TierraBG1_id1,"bat_a01",352,342; bg_warp $@TierraBG1_id2,"bat_a01",353,52; @@ -690,7 +701,8 @@ bat_a01,53,377,3 script Guillaume Vintenar#a01_a 419,{ callfunc "F_BG_Badge",1,"Guillaume","Tierra"; } bg_leave; - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; end; OnInit: @@ -712,7 +724,8 @@ bat_a01,45,19,3 script Croix Vintenar#a01_b 415,{ callfunc "F_BG_Badge",1,"Croix","Tierra"; } bg_leave; - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; end; OnInit: @@ -797,3 +810,21 @@ bat_a01,1,1,3 script Release all#a01 81,{ } } } + +// BG Queue makes these scripts useless +- script BGQueueInit#tierra01 -1,{ + end; + +OnInit: + if (getbattleflag("feature.bgqueue")) { + unloadnpc "Lieutenant Kalos"; + unloadnpc "Lieutenant Eyor"; + unloadnpc "#bat_a01_quest_a"; + unloadnpc "#bat_a01_quest_b"; + unloadnpc "back_bgrooma01a"; + unloadnpc "back_bgrooma01b"; + unloadnpc "A_CODE#bat_a01"; + unloadnpc "B_CODE#bat_a01"; + } + end; +} diff --git a/npc/battleground/tierra/tierra02.txt b/npc/battleground/tierra/tierra02.txt index 593aca84a6..3a00008ca9 100644 --- a/npc/battleground/tierra/tierra02.txt +++ b/npc/battleground/tierra/tierra02.txt @@ -1,23 +1,18 @@ -//===== rAthena Script ======================================= +//===== rAthena Script ======================================= //= BattleGround System - Tierra Gorge 2 -//===== By: ================================================== -//= L0ne_W0lf -//===== Current Version: ===================================== -//= 1.5 -//===== Compatible With: ===================================== -//= rAthena Project -//===== Description: ========================================= +//===== Description: ========================================= //= [Official Conversion] //= Second Tierra Gorge Battleground. //= - Winning Team: 3 badges (5 if VIP) //= - Losing Team: 1 badge (3 if VIP) -//===== Additional Comments: ================================= -//= 1.0 First Version. +//===== Changelogs: ========================================== +//= 1.0 First Version. [L0ne_W0lf] //= 1.1 Updated 'waitingroom' to support required zeny/lvl. [Kisuka] //= 1.2 Removed MaxLvl check in waitingrooms. //= 1.3 Label standardization. [Euphy] //= 1.4 Added GM management function. [Euphy] //= 1.5 Added VIP features and created a reward function. [Euphy] +//= 1.6 Added battle_config checks to allow this script to use the new queue interface or the previous method. [Aleos] //============================================================ // Waiting Room NPCs @@ -50,6 +45,8 @@ bat_room,1,151,3 script #bat_a02_timer 844,{ end; OnInit: + if (getbattleflag("feature.bgqueue")) + end; OnEnable: initnpctimer; end; @@ -60,14 +57,21 @@ OnStop: OnTimer1000: stopnpctimer; - initnpctimer; + if (!getbattleflag("feature.bgqueue")) + initnpctimer; set .@chk_bat_a02,getmapusers("bat_a02"); if (.@chk_bat_a02 < 1) { set $@TierraBG2,0; set $@TierraBG2_Victory, 0; if( $@TierraBG2_id1 ) { bg_destroy $@TierraBG2_id1; set $@TierraBG2_id1, 0; } if( $@TierraBG2_id2 ) { bg_destroy $@TierraBG2_id2; set $@TierraBG2_id2, 0; } - donpcevent "start#bat_a02::OnReadyCheck"; + if (getbattleflag("feature.bgqueue")) { + bg_unbook "bat_a02"; + end; + } else + donpcevent "start#bat_a02::OnReadyCheck"; } + if (getbattleflag("feature.bgqueue")) + initnpctimer; end; } @@ -123,23 +127,30 @@ OnEnable: OnGuillaumeQuit: OnCroixQuit: - bg_leave; + if (getbattleflag("feature.bgqueue")) + bg_desert; + else + bg_leave; end; OnReadyCheck: if( $@TierraBG2 ) end; - set .@Guillaume, getwaitingroomstate(0,"Lieutenant Rundel"); - set .@Croix, getwaitingroomstate(0,"Lieutenant Guerrit"); - if( !.@Guillaume && !.@Croix ) { - donpcevent "#bat_a02_timer::OnStop"; - end; + if (!getbattleflag("feature.bgqueue")) { + set .@Guillaume, getwaitingroomstate(0,"Lieutenant Rundel"); + set .@Croix, getwaitingroomstate(0,"Lieutenant Guerrit"); + if( !.@Guillaume && !.@Croix ) { + donpcevent "#bat_a02_timer::OnStop"; + end; + } + else if( .@Guillaume < 10 || .@Croix < 10 ) + end; } - else if( .@Guillaume < 10 || .@Croix < 10 ) - end; set $@TierraBG2,1; - donpcevent "Lieutenant Rundel::OnEnterBG"; - donpcevent "Lieutenant Guerrit::OnEnterBG"; + if (!getbattleflag("feature.bgqueue")) { + donpcevent "Lieutenant Rundel::OnEnterBG"; + donpcevent "Lieutenant Guerrit::OnEnterBG"; + } donpcevent "start#bat_a02::OnEnable"; bg_warp $@TierraBG2_id1,"bat_a02",352,342; bg_warp $@TierraBG2_id2,"bat_a02",353,52; @@ -689,7 +700,8 @@ bat_a02,53,377,3 script Guillaume Vintenar#a02_a 419,{ callfunc "F_BG_Badge",1,"Guillaume","Tierra"; } bg_leave; - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; end; OnInit: @@ -711,7 +723,8 @@ bat_a02,45,19,3 script Croix Vintenar#a02_b 415,{ callfunc "F_BG_Badge",1,"Croix","Tierra"; } bg_leave; - warp "bat_room",154,150; + if (getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; end; OnInit: @@ -796,3 +809,21 @@ bat_a02,1,1,3 script Release all#a02 81,{ } } } + +// BG Queue makes these scripts useless +- script BGQueueInit#tierra02 -1,{ + end; + +OnInit: + if (getbattleflag("feature.bgqueue")) { + unloadnpc "Lieutenant Rundel"; + unloadnpc "Lieutenant Guerrit"; + unloadnpc "#bat_a02_quest_a"; + unloadnpc "#bat_a02_quest_b"; + unloadnpc "back_bgrooma02a"; + unloadnpc "back_bgrooma02b"; + unloadnpc "A_CODE#bat_a02"; + unloadnpc "B_CODE#bat_a02"; + } + end; +} diff --git a/npc/battleground/tierra/tierra_enter.txt b/npc/battleground/tierra/tierra_enter.txt index c0e317c228..58ad3473f0 100644 --- a/npc/battleground/tierra/tierra_enter.txt +++ b/npc/battleground/tierra/tierra_enter.txt @@ -1,22 +1,19 @@ -//===== rAthena Script ======================================= +//===== rAthena Script ======================================= //= BattleGround System - Tierra Gorge Entrance NPCs -//===== By: ================================================== -//= L0ne_W0lf -//===== Current Version: ===================================== -//= 1.0 -//===== Compatible With: ===================================== -//= rAthena Project -//===== Description: ========================================= +//===== Description: ========================================= //= [Official Conversion] //= Tierra Gorge Battleground Entrance NPCs -//===== Additional Comments: ================================= -//= 1.0 First Version. +//===== Additional Comments: ================================= +//= 1.0 First Version. [L0ne_W0lf] //= 1.1 Fixed silly copy paste errors. (bugreport:4401) +//= 1.2 Added battle_config checks to allow this script to use the new queue interface or the previous method. [Aleos] //============================================================ // First Tierra Gorge Officers - Guillaume //============================================================ bat_room,124,178,5 script Tierra Gorge Officer#01a 418,{ + if (getbattleflag("feature.bgqueue")) + end; if (checkweight(1201,1) == 0) { mes "- Wait a minute !! -"; mes "- Currently you're carrying -"; @@ -84,6 +81,8 @@ bat_room,124,178,5 script Tierra Gorge Officer#01a 418,{ } bat_room,140,178,5 script Tierra Gorge Officer#02a 418,{ + if (getbattleflag("feature.bgqueue")) + end; if (checkweight(1201,1) == 0) { mes "- Wait a minute !! -"; mes "- Currently you're carrying -"; @@ -166,37 +165,22 @@ bat_room,127,178,5 script Guillaume Knight#1 417,{ mes "Think and move as quickly as you can. The victory of your army relies on your contribution."; next; mes "[Guillaume Knight]"; - mes "Please remember: when you join a battle, you will receive a token which indicates the set duration for which you cannot participate in the same type of battle."; - mes "You may check the duration by pressing the Alt+U keys."; + if (getbattleflag("feature.bgqueue")) + mes "If you are ready, start by clicking the ^0000FFbattle button from the interface^000000."; + else { + mes "Please remember: when you join a battle, you will receive a token which indicates the set duration for which you cannot participate in the same type of battle."; + mes "You may check the duration by pressing the Alt+U keys."; + } next; mes "[Guillaume Knight]"; - mes "Are you ready to battle? Then apply with the recruiter next to me!"; + if (getbattleflag("feature.bgqueue")) + mes "Please bear in mind once you cancel, ^0000FFyou may not reapply for 1 minute^000000!"; + else + mes "Are you ready to battle? Then apply with the recruiter next to me!"; close; } -bat_room,143,178,5 script Guillaume Knight#2 417,{ - mes "[Guillaume Knight]"; - mes "Tierra Gorge consists of two steep sides placed vertically, and has ration depots for the Guillaume and Croix Armies at the 11 and 7 o'clock directions."; - next; - mes "[Guillaume Knight]"; - mes "The battle starts at your army's ship, and the goal is to advance and destroy your enemy's rations depot faster than they can destroy yours."; - next; - mes "[Guillaume Knight]"; - mes "The healer of the battlefield will resurrect soldiers once every 25 seconds so that they can rejoin the battle."; - mes "The army that captures the neutral flag in the center of the battlefield will be rewarded with extra regeneration points, meaning their soldiers will resurrect more than the other side, giving them an advantage."; - next; - mes "[Guillaume Knight]"; - mes "Those two rations depots are connected to each other through short and narrow paths, but the gates are blocked with barricades."; - mes "Think and move as quickly as you can. The victory of your army relies on your contribution."; - next; - mes "[Guillaume Knight]"; - mes "Please remember: when you join a battle, you will receive a token which indicates the set duration for which you cannot participate in the same type of battle."; - mes "You may check the duration by pressing the Alt+U keys."; - next; - mes "[Guillaume Knight]"; - mes "Are you ready to battle? Then apply with the recruiter next to me!"; - close; -} +bat_room,143,178,5 duplicate(Guillaume Knight#1) Guillaume Knight#2 417 bat_room,127,121,1 script Croix Knight#1 413,{ mes "[Croix Knight]"; @@ -214,41 +198,28 @@ bat_room,127,121,1 script Croix Knight#1 413,{ mes "Think and move as quickly as you can. The victory of your army relies on your contribution."; next; mes "[Croix Knight]"; - mes "Please remember: when you join a battle, you will receive a token which indicates the set duration for which you cannot participate in the same type of battle."; - mes "You may check the duration by pressing the Alt+U keys."; + if (getbattleflag("feature.bgqueue")) + mes "If you are ready, start by clicking the ^0000FFbattle button from the interface^000000."; + else { + mes "Please remember: when you join a battle, you will receive a token which indicates the set duration for which you cannot participate in the same type of battle."; + mes "You may check the duration by pressing the Alt+U keys."; + } next; mes "[Croix Knight]"; - mes "Are you ready to battle? Then apply with the recruiter next to me!"; + if (getbattleflag("feature.bgqueue")) + mes "Please bear in mind once you cancel, ^0000FFyou may not reapply for 1 minute^000000!"; + else + mes "Are you ready to battle? Then apply with the recruiter next to me!"; close; } -bat_room,143,121,1 script Croix Knight#2 413,{ - mes "[Croix Knight]"; - mes "Tierra Gorge consists of two steep sides placed vertically, and has ration depots for the Guillaume and Croix Armies at the 11 and 7 o'clock directions."; - next; - mes "[Croix Knight]"; - mes "The battle starts at your army's ship, and the goal is to advance and destroy your enemy's rations depot faster than they can destroy yours."; - next; - mes "[Croix Knight]"; - mes "The healer of the battlefield will resurrect soldiers once every 25 seconds so that they can rejoin the battle."; - mes "The army that captures the neutral flag in the center of the battlefield will be rewarded with extra regeneration points, meaning their soldiers will resurrect more than the other side, giving them an advantage."; - next; - mes "[Croix Knight]"; - mes "Those two rations depots are connected to each other through short and narrow paths, but the gates are blocked with barricades."; - mes "Think and move as quickly as you can. The victory of your army relies on your contribution."; - next; - mes "[Croix Knight]"; - mes "Please remember: when you join a battle, you will receive a token which indicates the set duration for which you cannot participate in the same type of battle."; - mes "You may check the duration by pressing the Alt+U keys."; - next; - mes "[Croix Knight]"; - mes "Are you ready to battle? Then apply with the recruiter next to me!"; - close; -} +bat_room,143,121,1 duplicate(Croix Knight#1) Croix Knight#2 413 // Second Tierra Gorge Officers - Croix //============================================================ bat_room,125,121,1 script Tierra Gorge Officer#01b 414,{ + if (getbattleflag("feature.bgqueue")) + end; if (checkweight(1201,1) == 0) { mes "- Wait a minute !! -"; mes "- Currently you're carrying -"; @@ -316,6 +287,8 @@ bat_room,125,121,1 script Tierra Gorge Officer#01b 414,{ } bat_room,140,121,1 script Tierra Gorge Officer#02b 414,{ + if (getbattleflag("feature.bgqueue")) + end; if (checkweight(1201,1) == 0) { mes "- Wait a minute !! -"; mes "- Currently you're carrying -"; diff --git a/npc/custom/battleground/unofficial/bg_common.txt b/npc/custom/battleground/unofficial/bg_common.txt deleted file mode 100644 index 49ddf2fcbc..0000000000 --- a/npc/custom/battleground/unofficial/bg_common.txt +++ /dev/null @@ -1,1288 +0,0 @@ -// ============================================================================== -// BattleGround System - Common NPCs -// ============================================================================== - -// BattleGround Warper - Entrance -// ********************************************************************* - -- script Maroll Battle Recruiter::BatRecruit 728,{ - mes "[Maroll Battle Recruiter]"; - mes "Good day, adventurer."; - mes "I'm a knight from a far country called Maroll Kingdom."; - next; - mes "[Maroll Battle Recruiter]"; - mes "The two princes of the kingdom are now battling for the throne of Maroll, and are in need of experienced soldiers like you. How would you like to lend your power to one of the princes in the Maroll Kingdom?"; - next; - if( select("Join:Don't Join") == 2 ) - { - mes "[Maroll Battle Recruiter]"; - mes "I'll always be stationed here for more soldiers. Feel free to come back whenever you're interested."; - close; - } - mes "[Maroll Battle Recruiter]"; - mes "May the war god bless you."; - close2; - warp "bat_room",155,150; - end; -} - -payon,189,104,3 duplicate(BatRecruit) Maroll Battle Recruiter::BatRecruit1 728 -prontera,123,83,5 duplicate(BatRecruit) Maroll Battle Recruiter::BatRecruit2 728 -rachel,149,138,5 duplicate(BatRecruit) Maroll Battle Recruiter::BatRecruit3 728 -moc_ruins,75,162,5 duplicate(BatRecruit) Maroll Battle Recruiter::BatRecruit4 728 -aldebaran,146,109,5 duplicate(BatRecruit) Maroll Battle Recruiter::BatRecruit5 728 -lighthalzen,153,86,5 duplicate(BatRecruit) Maroll Battle Recruiter::BatRecruit6 728 - -// BattleGround Warper - Exit -// ********************************************************************* - -bat_room,148,150,4 script Teleporter#bat 124,{ - mes "[Teleporter]"; - mes "Do you wish to leave the battlefield? Use my service to return to town."; - next; - if( select("Leave:Don't Leave") == 2 ) - { - mes "[Teleporter]"; - mes "I'll be here whenever you're in need of my service."; - close; - } - - set .@spoint$, getsavepoint(0); - set .@x, getsavepoint(1); - set .@y, getsavepoint(2); - mes "[Teleporter]"; - mes "You will be sent back to " + .@spoint$ + "."; - close2; - warp .@spoint$, .@x, .@y; - end; -} - -// Kafra -// ********************************************************************* -bat_room,148,147,4 script Kafra Staff::kaf_bat 861,{ - cutin "kafra_09",2; - callfunc "F_Kafra",0,2,1,150,0; -} - -// General Guillaume -// ********************************************************************* -bat_room,160,159,3 script General Guillaume 420,{ - cutin "bat_kiyom2",2; - mes "[General Guillaume]"; - mes "Hot-blooded adventurer, we need your ability to win this battle."; - next; - cutin "bat_kiyom1",2; - mes "[General Guillaume]"; - mes "Our great king, Marcel Marollo VII, is very sick lately. His Majesty has declared that he chosen either me or Prince Croix as the next king amongst his 9 sons."; - next; - mes "[General Guillaume]"; - mes "Two kings can't share a nation!"; - mes "Only the one victorious from His Majesty's appointed battle will be enthroned."; - next; - mes "[General Guillaume]"; - mes "This is however, not just a battle between us. This battle will determine the future of this country. I pledge on my honor to prove that I'm the one who can protect this Maroll from outside threats."; - next; - if( select("Yes, I want to join you.:End Conversation") == 2 ) - { - mes "[General Guillaume]"; - mes "I'll be the one who will capture the flag!"; - close2; - cutin "",255; - end; - } - cutin "bat_kiyom2",2; - mes "[General Guillaume]"; - mes "Welcome to my army, comrade."; - mes "Your eyes tell me that you're a soldier that I can trust."; - set Bat_Team,1; - next; - mes "[General Guillaume]"; - mes "Now, go upstairs and apply for battle with your comrades. I'm sure they'll welcome you whole-heartedly!"; - close2; - cutin "",255; - end; -} - -// General Croix -// ********************************************************************* -bat_room,160,140,3 script Prince Croix 416,{ - cutin "bat_crua1",2; - mes "[Prince Croix]"; - mes "Wise adventurer, why don't you lend us your power for victory?"; - next; - cutin "bat_crua2",2; - mes "[Prince Croix]"; - mes "I do not wish to shed blood, but I have no choice but to fight for the possibility of peace and for the sake of my people."; - next; - mes "[Prince Croix]"; - mes "General Guillaume may have an advantage in this battle as he is the great general of Maroll, but that doesn't automatically mean he'll win. I want to win this battle so that I can grant a better future for my people."; - next; - if( select("Yes, I want to join you!:End Conversation") == 2 ) - { - mes "[Prince Croix]"; - mes "For Maroll!"; - close2; - cutin "",255; - end; - } - mes "[Prince Croix]"; - mes "Thank you so much. I feel like I can win with the help of adventurers like you. Now, please go downstairs and join your comrades in sharpening their skills to fight the enemy!"; - set Bat_Team,2; - close2; - cutin "",255; - end; -} - -// Guillaume Knight - Tierra Valley -// ********************************************************************* -bat_room,159,178,5 script Guillaume Knight#1 417,{ - mes "[Guillaume Knight]"; - mes "Tierra Gorge is a very steep canyon with two forts residing in the north and south ends of the map."; - next; - mes "[Guillaume Knight]"; - mes "There is a ration depot for the Guillaume and Croix armies at the 11 and 8 o'clock directions."; - next; - mes "[Guillaume Knight]"; - mes "The battle starts at your army's ship, and the goal is to advance and destroy your enemy's rations depot faster than they can destroy yours."; - mes "The army that captures the neutral flag in the center of the battlefield will be rewarded with extra regeneration points, meaning their soldiers will resurrect more than the other side, giving them an advantage."; - next; - mes "[Guillaume Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// Tierra Officer - Guillaume -// ********************************************************************* -bat_room,156,178,5 script Tierra Valley Officer#1 418,{ - mes "[Tierra Officer]"; - if( Bat_Team == 2 ) - { - mes "Get out of here you stinky Croix!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Guillaume Army to those stinky Croixs!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[Tierra Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(2069,PLAYTIME) == 2 ) erasequest 2069; - if( checkquest(2069,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at Tierra Gorge. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[Tierra Officer]"; - mes "Stand-by for Tierra Gorge Battle until the time limit passes."; - close; - } - - if( BaseLevel < 80 ) - { - mes "I'm very please you want to join our army, but I'm sorry: I can't send a rookie like you to die on the cruel battlefield"; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",85,224; - end; -} - -// Croix Knight - Tierra Valley -// ********************************************************************* -bat_room,159,121,1 script Croix Knight#1 413,{ - mes "[Croix Knight]"; - mes "Tierra Gorge is a very steep canyon with two forts residing in the north and south ends of the map."; - next; - mes "[Croix Knight]"; - mes "There is a ration depot for the Guillaume and Croix armies at the 11 and 8 o'clock directions."; - next; - mes "[Croix Knight]"; - mes "The battle starts at your army's ship, and the goal is to advance and destroy your enemy's rations depot faster than they can destroy yours."; - mes "The army that captures the neutral flag in the center of the battlefield will be rewarded with extra regeneration points, meaning their soldiers will resurrect more than the other side, giving them an advantage."; - next; - mes "[Croix Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// Tierra Officer - Croix -// ********************************************************************* -bat_room,156,121,1 script Tierra Valley Officer#2 414,{ - mes "[Tierra Officer]"; - if( Bat_Team == 1 ) - { - mes "Get out of here you stupid Guillaume!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Croix Army to those stinky Guillaumes!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[Tierra Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(2069,PLAYTIME) == 2 ) erasequest 2069; - if( checkquest(2069,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at Tierra Gorge. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[Tierra Officer]"; - mes "Stand-by for Tierra Gorge Battle until the time limit passes."; - close; - } - - if( BaseLevel < 80 ) - { - mes "I'm very please you want to join our army, but I'm sorry: I can't send a rookie like you to die on the cruel battlefield"; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",85,208; - end; -} - -// Guillaume Knight - Tierra -// ********************************************************************* -bat_room,167,178,5 script Guillaume Knight#2 417,{ - mes "[Guillaume Knight]"; - mes "Tierra Gorge is a very steep canyon with two forts residing in the north and south ends of the map."; - next; - mes "[Guillaume Knight]"; - mes "There is a ration depot for the Guillaume and Croix armies at the 11 and 8 o'clock directions."; - next; - mes "[Guillaume Knight]"; - mes "The battle starts at your army's ship, and the goal is to advance and destroy your enemy's rations depot faster than they can destroy yours."; - mes "The army that captures the neutral flag in the center of the battlefield will be rewarded with extra regeneration points, meaning their soldiers will resurrect more than the other side, giving them an advantage."; - next; - mes "[Guillaume Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// Tierra Officer - Guillaume -// ********************************************************************* -bat_room,164,178,5 script Tierra Valley Officer#3 418,{ - mes "[Tierra Officer]"; - if( Bat_Team == 2 ) - { - mes "Get out of here you stinky Croix!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Guillaume Army to those stinky Croixs!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[Tierra Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(2069,PLAYTIME) == 2 ) erasequest 2069; - if( checkquest(2069,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at Tierra Gorge. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[Tierra Officer]"; - mes "Stand-by for Tierra Gorge Battle until the time limit passes."; - close; - } - - if( BaseLevel < 80 ) - { - mes "I'm very please you want to join our army, but I'm sorry: I can't send a rookie like you to die on the cruel battlefield"; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",57,94; - end; -} - -// Croix Knight - Tierra -// ********************************************************************* -bat_room,167,121,1 script Croix Knight#2 413,{ - mes "[Croix Knight]"; - mes "Tierra Gorge is a very steep canyon with two forts residing in the north and south ends of the map."; - next; - mes "[Croix Knight]"; - mes "There is a ration depot for the Guillaume and Croix armies at the 11 and 8 o'clock directions."; - next; - mes "[Croix Knight]"; - mes "The battle starts at your army's ship, and the goal is to advance and destroy your enemy's rations depot faster than they can destroy yours."; - mes "The army that captures the neutral flag in the center of the battlefield will be rewarded with extra regeneration points, meaning their soldiers will resurrect more than the other side, giving them an advantage."; - next; - mes "[Croix Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// Tierra Officer - Croix -// ********************************************************************* -bat_room,164,121,1 script Tierra Valley Officer#4 414,{ - mes "[Tierra Officer]"; - if( Bat_Team == 1 ) - { - mes "Get out of here you stupid Guillaume!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Croix Army to those stinky Guillaumes!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[Tierra Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(2069,PLAYTIME) == 2 ) erasequest 2069; - if( checkquest(2069,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at Tierra Gorge. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[Tierra Officer]"; - mes "Stand-by for Tierra Gorge Battle until the time limit passes."; - close; - } - - if( BaseLevel < 80 ) - { - mes "I'm very please you want to join our army, but I'm sorry: I can't send a rookie like you to die on the cruel battlefield"; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",57,77; - end; -} - -// Guillaune Knight - Flavius -// ********************************************************************* -bat_room,175,178,5 script Guillaume Knight#3 417,{ - mes "[Guillaume Knight]"; - mes "The objective of the Flavius Battle is to score 2 points before your enemy by destroying their crystal."; - next; - mes "[Guillaume Knight]"; - mes "The crystals for both armies are protected by special barricades that cannot be destroyed by direct attacks."; - next; - mes "[Guillaume Knight]"; - mes "But they can be removed by destroying the Guardians that protect the enemy army base."; - next; - mes "[Guillaume Knight]"; - mes "The crystals are immune to every type of skill; your physical attacks are the only choice for destroying your enemy's crystal."; - next; - mes "[Guillaume Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// Flavius Officer - Guillaume -// ********************************************************************* -bat_room,172,178,5 script Flavius Officer#1 418,{ - mes "[Flavius Officer]"; - if( Bat_Team == 2 ) - { - mes "Get out of here you stupid Croix!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Guillaume Army to those stinky Croixs!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[Flavius Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(2070,PLAYTIME) == 2 ) erasequest 2070; - if( checkquest(2070,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at Flavius. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[Flavius Officer]"; - mes "Stand-by for Flavius Battle until the time limit passes."; - close; - } - - if( BaseLevel < 80 ) - { - mes "I'm very please you want to join our army, but I'm sorry: I can't send a rookie like you to die on the cruel battlefield"; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",85,94; - end; -} - -// Croix Knight - Flavius -// ********************************************************************* -bat_room,175,121,1 script Croix Knight#3 413,{ - mes "[Croix Knight]"; - mes "The objective of the Flavius Battle is to score 2 points before your enemy by destroying their crystal."; - next; - mes "[Croix Knight]"; - mes "The crystals for both armies are protected by special barricades that cannot be destroyed by direct attacks."; - next; - mes "[Croix Knight]"; - mes "But they can be removed by destroying the Guardians that protect the enemy army base."; - next; - mes "[Croix Knight]"; - mes "The crystals are immune to every type of skill; your physical attacks are the only choice for destroying your enemy's crystal."; - next; - mes "[Croix Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// Flavius Officerer - Croix -// ********************************************************************* -bat_room,172,121,1 script Flavius Officer#2 414,{ - mes "[Flavius Officer]"; - if( Bat_Team == 1 ) - { - mes "Get out of here you stupid Guillaume!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Croix Army to those stinky Guillaumes!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[Flavius Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(2070,PLAYTIME) == 2 ) erasequest 2070; - if( checkquest(2070,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at Flavius. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[Flavius Officer]"; - mes "Stand-by for Flavius Battle until the time limit passes."; - close; - } - - if( BaseLevel < 80 ) - { - mes "I'm very please you want to join our army, but I'm sorry: I can't send a rookie like you to die on the cruel battlefield"; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",85,77; - end; -} - -// Guillaune Knight - Flavius -// ********************************************************************* -bat_room,151,178,5 script Guillaume Knight#4 417,{ - mes "[Guillaume Knight]"; - mes "The objective of the Flavius Battle is to score 2 points before your enemy by destroying their crystal."; - next; - mes "[Guillaume Knight]"; - mes "The crystals for both armies are protected by special barricades that cannot be destroyed by direct attacks."; - next; - mes "[Guillaume Knight]"; - mes "But they can be removed by destroying the Guardians that protect the enemy army base."; - next; - mes "[Guillaume Knight]"; - mes "The crystals are immune to every type of skill; your physical attacks are the only choice for destroying your enemy's crystal."; - next; - mes "[Guillaume Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// Flavius Officerer - Guillaume -// ********************************************************************* -bat_room,148,178,5 script Flavius Officer#3 418,{ - mes "[Flavius Officer]"; - if( Bat_Team == 2 ) - { - mes "Get out of here you stupid Croix!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Guillaume Army to those stinky Croixs!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[Flavius Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(2070,PLAYTIME) == 2 ) erasequest 2070; - if( checkquest(2070,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at Flavius. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[Flavius Officer]"; - mes "Stand-by for Flavius Battle until the time limit passes."; - close; - } - - if( BaseLevel < 80 ) - { - mes "I'm very please you want to join our army, but I'm sorry: I can't send a rookie like you to die on the cruel battlefield"; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",253,94; - end; -} - -// Croix Knight - Flavius -// ********************************************************************* -bat_room,151,121,1 script Croix Knight#4 413,{ - mes "[Croix Knight]"; - mes "The objective of the Flavius Battle is to score 2 points before your enemy by destroying their crystal."; - next; - mes "[Croix Knight]"; - mes "The crystals for both armies are protected by special barricades that cannot be destroyed by direct attacks."; - next; - mes "[Croix Knight]"; - mes "But they can be removed by destroying the Guardians that protect the enemy army base."; - next; - mes "[Croix Knight]"; - mes "The crystals are immune to every type of skill; your physical attacks are the only choice for destroying your enemy's crystal."; - next; - mes "[Croix Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// Flavius Officerer - Croix -// ********************************************************************* -bat_room,148,121,1 script Flavius Officer#4 414,{ - mes "[Flavius Officer]"; - if( Bat_Team == 1 ) - { - mes "Get out of here you stupid Guillaume!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Croix Army to those stinky Guillaumes!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[Flavius Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(2070,PLAYTIME) == 2 ) erasequest 2070; - if( checkquest(2070,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at Flavius. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[Flavius Officer]"; - mes "Stand-by for Flavius Battle until the time limit passes."; - close; - } - - if( BaseLevel < 80 ) - { - mes "I'm very please you want to join our army, but I'm sorry: I can't send a rookie like you to die on the cruel battlefield"; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",253,77; - end; -} - -// Guillaume Knight - KvM -// ********************************************************************* -bat_room,143,178,5 script Guillaume Knight#5 417,{ - mes "[Guillaume Knight]"; - mes "To win the Battle of Kriger Von Midgard you and your team must kill all the other opponents before all of you die."; - next; - mes "[Guillaume Knight]"; - mes "The first team to lose all their soldiers loses."; - next; - mes "[Guillaume Knight]"; - mes "Since you cannot come back to battle after you die, taking care on the battlefield is essential."; - next; - mes "[Guillaume Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// KvM Officerer - Guillaume -// ********************************************************************* -bat_room,140,178,5 script KVM [80-99] Officer#1 418,{ - mes "[KVM Officer]"; - if( Bat_Team == 2 ) - { - mes "Get out of here you stinky Croix!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Guillaume Army to those stinky Croixs!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[KVM Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(6025,PLAYTIME) == 2 ) erasequest 6025; - if( checkquest(6025,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at KvM. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[KVM Officer]"; - mes "Stand-by for KvM Battle until the time limit passes."; - close; - } - - if( BaseLevel < 80 ) - { - mes "I'm very please you want to join our army, but I'm sorry: This arena is for players with baselevel from 80 to 99."; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",253,224; - end; -} - -// Croix Knight - KvM -// ********************************************************************* -bat_room,143,121,1 script Croix Knight#5 413,{ - mes "[Croix Knight]"; - mes "To win the Battle of Kriger Von Midgard you and your team must kill all the other opponents before all of you die."; - next; - mes "[Croix Knight]"; - mes "The first team to lose all their soldiers loses."; - next; - mes "[Croix Knight]"; - mes "Since you cannot come back to battle after you die, taking care on the battlefield is essential."; - next; - mes "[Croix Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// KvM Officer - Croix -// ********************************************************************* -bat_room,140,121,1 script KVM [80-99] Officer#2 414,{ - mes "[KVM Officer]"; - if( Bat_Team == 1 ) - { - mes "Get out of here you stupid Guillaume!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Croix Army to those stinky Guillaumes!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[KVM Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(6025,PLAYTIME) == 2 ) erasequest 6025; - if( checkquest(6025,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at KvM. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[KVM Officer]"; - mes "Stand-by for KvM Battle until the time limit passes."; - close; - } - - if( BaseLevel < 80 ) - { - mes "I'm very please you want to join our army, but I'm sorry: This arena is for players with baselevel from 80 to 99."; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",253,208; - end; -} - -// Guillaume Knight - KvM -// ********************************************************************* -bat_room,135,178,5 script Guillaume Knight#6 417,{ - mes "[Guillaume Knight]"; - mes "To win the Battle of Kriger Von Midgard you and your team must kill all the other opponents before all of you die."; - next; - mes "[Guillaume Knight]"; - mes "The first team to lose all their soldiers loses."; - next; - mes "[Guillaume Knight]"; - mes "Since you cannot come back to battle after you die, taking care on the battlefield is essential."; - next; - mes "[Guillaume Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// KvM Officerer - Guillaume -// ********************************************************************* -bat_room,132,178,5 script KVM [60-79] Officer#1 418,{ - mes "[KVM Officer]"; - if( Bat_Team == 2 ) - { - mes "Get out of here you stinky Croix!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Guillaume Army to those stinky Croixs!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[KVM Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(6025,PLAYTIME) == 2 ) erasequest 6025; - if( checkquest(6025,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at KvM. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[KVM Officer]"; - mes "Stand-by for KvM Battle until the time limit passes."; - close; - } - - if( BaseLevel < 60 || BaseLevel > 79 ) - { - mes "I'm very please you want to join our army, but I'm sorry: This arena is for players with baselevel from 60 to 79."; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",225,224; - end; -} - -// Croix Knight - KvM -// ********************************************************************* -bat_room,135,121,1 script Croix Knight#6 413,{ - mes "[Croix Knight]"; - mes "To win the Battle of Kriger Von Midgard you and your team must kill all the other opponents before all of you die."; - next; - mes "[Croix Knight]"; - mes "The first team to lose all their soldiers loses."; - next; - mes "[Croix Knight]"; - mes "Since you cannot come back to battle after you die, taking care on the battlefield is essential."; - next; - mes "[Croix Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// KvM Officer - Croix -// ********************************************************************* -bat_room,132,121,1 script KVM [60-79] Officer#2 414,{ - mes "[KVM Officer]"; - if( Bat_Team == 1 ) - { - mes "Get out of here you stupid Guillaume!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Croix Army to those stinky Guillaumes!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[KVM Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(6025,PLAYTIME) == 2 ) erasequest 6025; - if( checkquest(6025,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at KvM. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[KVM Officer]"; - mes "Stand-by for KvM Battle until the time limit passes."; - close; - } - - if( BaseLevel < 60 || BaseLevel > 79 ) - { - mes "I'm very please you want to join our army, but I'm sorry: This arena is for players with baselevel from 60 to 79."; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",225,208; - end; -} - -// Guillaume Knight - KvM -// ********************************************************************* -bat_room,127,178,5 script Guillaume Knight#7 417,{ - mes "[Guillaume Knight]"; - mes "To win the Battle of Kriger Von Midgard you and your team must kill all the other opponents before all of you die."; - next; - mes "[Guillaume Knight]"; - mes "The first team to lose all their soldiers loses."; - next; - mes "[Guillaume Knight]"; - mes "Since you cannot come back to battle after you die, taking care on the battlefield is essential."; - next; - mes "[Guillaume Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// KvM Officerer - Guillaume -// ********************************************************************* -bat_room,124,178,5 script KVM [1-59] Officer#1 418,{ - mes "[KVM Officer]"; - if( Bat_Team == 2 ) - { - mes "Get out of here you stinky Croix!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Guillaume Army to those stinky Croixs!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[KVM Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(6025,PLAYTIME) == 2 ) erasequest 6025; - if( checkquest(6025,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at KvM. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[KVM Officer]"; - mes "Stand-by for KvM Battle until the time limit passes."; - close; - } - - if( BaseLevel > 59 ) - { - mes "I'm very please you want to join our army, but I'm sorry: This arena is for players with baselevel from 1 to 59."; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",197,224; - end; -} - -// Croix Knight - KvM -// ********************************************************************* -bat_room,127,121,1 script Croix Knight#7 413,{ - mes "[Croix Knight]"; - mes "To win the Battle of Kriger Von Midgard you and your team must kill all the other opponents before all of you die."; - next; - mes "[Croix Knight]"; - mes "The first team to lose all their soldiers loses."; - next; - mes "[Croix Knight]"; - mes "Since you cannot come back to battle after you die, taking care on the battlefield is essential."; - next; - mes "[Croix Knight]"; - mes "Are you ready for battle? Then apply with the recruiter next to me!"; - close; -} - -// KvM Officer - Croix -// ********************************************************************* -bat_room,124,121,1 script KVM [1-59] Officer#2 414,{ - mes "[KVM Officer]"; - if( Bat_Team == 1 ) - { - mes "Get out of here you stupid Guillaume!"; - close; - } - - if( Bat_Team == 0 ) - { - mes "Please sign up for an army with Prince Croix or General Guillaume!"; - close; - } - - mes "Hello " + strcharinfo(0) + ", let's show the power of the Croix Army to those stinky Guillaumes!"; - next; - if( select("I want to join your army!:End Conversation") == 2 ) - close; - - mes "[KVM Officer]"; - if( BG_Delay_Tick >= gettimetick(2) ) - { - mes "You are a Deserter!!"; - mes "Because of running away, you need to wait ^0000FF" + callfunc("Time2Str",BG_Delay_Tick) + "^000000 to join again a BattleGround."; - close; - } - - if( checkquest(6025,PLAYTIME) == 2 ) erasequest 6025; - if( checkquest(6025,PLAYTIME) != -1 ) - { - mes "You have received an indicator showing that you've participated in the Battle at KvM. I can't let you participate in any other battles until the indicator goes off."; - next; - mes "[KVM Officer]"; - mes "Stand-by for KvM Battle until the time limit passes."; - close; - } - - if( BaseLevel > 59 ) - { - mes "I'm very please you want to join our army, but I'm sorry: This arena is for players with baselevel from 1 to 59."; - close; - } - - mes "Good luck!"; - close2; - warp "bat_room",197,208; - end; -} - -// Guard Dummy -// ********************************************************************* - -bat_room,161,141,3 script Prince Croix's Aid::bat_aid 415,{ end; } -bat_room,161,139,3 duplicate(bat_aid) Prince Croix's Aid::bat_aid2 415 -bat_room,161,160,3 duplicate(bat_aid) General Guillaume's Aid::bat_aid3 419 -bat_room,161,158,3 duplicate(bat_aid) General Guillaume's Aid::bat_aid4 419 - -// Flags -// ********************************************************************* - -- script Guillaume camp#bat 973,{ end; } -- script Croix camp#bat 974,{ end; } - -// Exit from Registration -// ********************************************************************* -- script warp2bat_room -1,{ - end; - -OnTouch: - set BG_Delay_Tick, gettimetick(2) + 30; - warp "bat_room",154,149; - end; -} - -// Flavius bat_b02 -bat_room,57,81,0 duplicate(warp2bat_room) bat1 45,1,1 -bat_room,57,90,0 duplicate(warp2bat_room) bat2 45,1,1 -// Free BG -bat_room,57,220,0 duplicate(warp2bat_room) bat3 45,1,1 -bat_room,57,211,0 duplicate(warp2bat_room) bat4 45,1,1 -// Tierra Valley bat_a02 -bat_room,85,81,0 duplicate(warp2bat_room) bat5 45,1,1 -bat_room,85,90,0 duplicate(warp2bat_room) bat6 45,1,1 -// Tierra Valley bat_a01 -bat_room,85,220,0 duplicate(warp2bat_room) bat7 45,1,1 -bat_room,85,211,0 duplicate(warp2bat_room) bat8 45,1,1 -// Free BG -bat_room,113,81,0 duplicate(warp2bat_room) bat9 45,1,1 -bat_room,113,90,0 duplicate(warp2bat_room) bat10 45,1,1 -// Free BG -bat_room,113,220,0 duplicate(warp2bat_room) bat11 45,1,1 -bat_room,113,211,0 duplicate(warp2bat_room) bat12 45,1,1 -// Free BG -bat_room,141,81,0 duplicate(warp2bat_room) bat13 45,1,1 -bat_room,141,90,0 duplicate(warp2bat_room) bat14 45,1,1 -// Free BG -bat_room,141,220,0 duplicate(warp2bat_room) bat15 45,1,1 -bat_room,141,211,0 duplicate(warp2bat_room) bat16 45,1,1 -// Free BG -bat_room,169,81,0 duplicate(warp2bat_room) bat17 45,1,1 -bat_room,169,90,0 duplicate(warp2bat_room) bat18 45,1,1 -// Free BG -bat_room,169,220,0 duplicate(warp2bat_room) bat19 45,1,1 -bat_room,169,211,0 duplicate(warp2bat_room) bat20 45,1,1 -// Free BG -bat_room,197,81,0 duplicate(warp2bat_room) bat21 45,1,1 -bat_room,197,90,0 duplicate(warp2bat_room) bat22 45,1,1 -// KvM bat_c03 -bat_room,197,220,0 duplicate(warp2bat_room) bat23 45,1,1 -bat_room,197,211,0 duplicate(warp2bat_room) bat24 45,1,1 -// Free BG -bat_room,225,81,0 duplicate(warp2bat_room) bat25 45,1,1 -bat_room,225,90,0 duplicate(warp2bat_room) bat26 45,1,1 -// KvM bat_c02 -bat_room,225,220,0 duplicate(warp2bat_room) bat27 45,1,1 -bat_room,225,211,0 duplicate(warp2bat_room) bat28 45,1,1 -// Flavius bat_b01 -bat_room,253,81,0 duplicate(warp2bat_room) bat29 45,1,1 -bat_room,253,90,0 duplicate(warp2bat_room) bat30 45,1,1 -// KvM bat_c01 -bat_room,253,220,0 duplicate(warp2bat_room) bat31 45,1,1 -bat_room,253,211,0 duplicate(warp2bat_room) bat32 45,1,1 - -// Badges Repairman -// ********************************************************************* - -bat_room,138,144,5 script Repairman#bg 99,{ - callfunc "repairmain","Repairman"; - end; -} - -// Badges Exchange -// ********************************************************************* - -bat_room,160,150,3 script Erundek 109,{ - mes "[Erundek]"; - mes "Welcome, mighty warrior."; - mes "What can I do for you today ?"; - next; - switch( select("Check the Catalog","Exchange Bravery Badges","Exchange Valor Badges","Exchange Heroism Badges","Hmm, nothing I guess.") ) - { - case 1: - mes "[Erundek]"; - mes "We have many items, so please take a look and purchase deliberately."; - close2; - readbook 11010,1; - end; - case 5: - mes "[Erundek]"; - mes "As you wish."; - mes "See you later."; - close; - case 2: // Bravery Badges - mes "[Erundek]"; - mes "So you want to exchange ^0000FFBravery Badges^000000 from the Battle of Tierra Valley."; - mes "What kind of item do you want to exchange?"; - next; - deletearray .@Item_DB[0],127; - set .@Badge, 7828; - - switch( select("Weapons:Garment:Footgear:Armor:Accessory") ) - { - case 1: setarray .@Item_DB[0],13036,13411,1425,1632,1634,1543,1924,1978,1574,1824,1183,1380,13305,1279,1739,13108,13172; set .@Value, 100; break; - case 2: setarray .@Item_DB[0],2538,2539,2540; set .@Value, 50; break; - case 3: setarray .@Item_DB[0],2435,2436,2437; set .@Value, 50; break; - case 4: setarray .@Item_DB[0],2376,2377,2378,2379,2380,2381,2382; set .@Value, 80; break; - case 5: setarray .@Item_DB[0],2720,2721,2722,2723,2724,2725,2733; set .@Value, 500; break; - } - - break; - case 3: // Valor Badges - mes "[Erundek]"; - mes "So you want to exchange ^FF0000Valor Badges^000000 from the Battle of Flavius."; - mes "What kind of item do you want to exchange?"; - next; - deletearray .@Item_DB[0],127; - set .@Badge, 7829; - - switch( select("Weapons:Garment:Footgear:Armor:Accessory") ) - { - case 1: setarray .@Item_DB[0],13037,13410,1633,1635,1542,1923,1977,1575,1823,1184,1482,1379,13306,1280,1738,13171,13173,13174; set .@Value, 100; break; - case 2: setarray .@Item_DB[0],2538,2539,2540; set .@Value, 50; break; - case 3: setarray .@Item_DB[0],2435,2436,2437; set .@Value, 50; break; - case 4: setarray .@Item_DB[0],2376,2377,2378,2379,2380,2381,2382; set .@Value, 80; break; - case 5: setarray .@Item_DB[0],2720,2721,2722,2723,2724,2725,2733; set .@Value, 500; break; - } - - break; - case 4: // Heroism Badge - mes "[Erundek]"; - mes "So you want to exchange ^FFA500Heroism Badges^000000 from the Battle of Kriger Von Midgard."; - mes "This shop is not available at the moment."; - close; - } - - mes "[Erundek]"; - mes "What item do you want to exchange?"; - mes "If you are not sure, check the catalog."; - next; - - set .@Menu$, ""; - set .@Count, getarraysize(.@Item_DB); - for( set .@i, 0; .@i < .@Count; set .@i, .@i + 1 ) - set .@Menu$, .@Menu$ + getitemname(.@Item_DB[.@i]) + ":"; - - set .@Item_ID, .@Item_DB[select(.@Menu$) - 1]; - - mes "[Erundek]"; - mes "Would you like to exchange ^FF0000" + .@Value + " " + getitemname(.@Badge) + "^000000 for a ^0000FF" + getitemname(.@Item_ID) + "^000000?"; - next; - mes "Remember, Battleground Reward Items are ^FF0000Character Bound^000000."; - mes "Are you sure you want this item?"; - next; - - if( select("Yes:No") == 2 ) - { - mes "[Erundek]"; - mes "Do you need more time to check the items?"; - close; - } - - if( countitem(.@Badge) < .@Value ) - { - mes "[Erundek]"; - mes "I'm sorry, but you don't have enough badges to exchange."; - close; - } - - delitem .@Badge,.@Value; - getitem .@Item_ID,1; - mes "[Erundek]"; - mes "Thank you for exchanging."; - close; -} diff --git a/npc/custom/battleground/unofficial/bg_flavius_01.txt b/npc/custom/battleground/unofficial/bg_flavius_01.txt deleted file mode 100644 index f940ab875c..0000000000 --- a/npc/custom/battleground/unofficial/bg_flavius_01.txt +++ /dev/null @@ -1,428 +0,0 @@ -// ============================================================================== -// BattleGround System - Flavius 1 -// ============================================================================== - -// Registration NPC's -// ********************************************************************* - -bat_room,86,227,4 script Registration::Fl1R_Guillaume 418,{ - end; -OnInit: - waitingroom "Battle Station 10 Players",10,"Flavius_BG1::OnGuillaumeJoin",1; - end; -OnEnterBG: - set $@FlaviusBG1_id1, waitingroom2bg("bat_b01",390,10,"Flavius_BG1::OnGuillaumeQuit",""); - end; -} - -bat_room,85,204,0 script Registration::Fl1R_Croix 414,{ - end; -OnInit: - waitingroom "Battle Station 10 Players",10,"Flavius_BG1::OnCroixJoin",1; - end; -OnEnterBG: - set $@FlaviusBG1_id2, waitingroom2bg("bat_b01",10,290,"Flavius_BG1::OnCroixQuit",""); - end; -} - -// Battleground Engine -// ********************************************************************* - -- script Flavius_BG1 -1,{ - end; - -OnInit: - disablenpc "Guillaume Vintenar#fl1"; - disablenpc "Croix Vintenar#fl1"; - disablenpc "Therapist in battle#fl11"; - disablenpc "Therapist in battle#fl12"; - end; - -OnGuillaumeQuit: -OnCroixQuit: - set BG_Delay_Tick, gettimetick(2) + 1200; - end; - -OnGuillaumeJoin: -OnCroixJoin: - if( $@FlaviusBG1 == 0 ) - donpcevent "Flavius_BG1::OnReadyCheck"; - end; - -OnReadyCheck: - if( $@FlaviusBG1 ) - end; - set .@Guillaume, getwaitingroomstate(0,"Fl1R_Guillaume"); - set .@Croix, getwaitingroomstate(0,"Fl1R_Croix"); - - if( .@Guillaume < 10 || .@Croix < 10 ) - { - mapannounce "bat_room","Battleground -- Flavius [80-99] G: " + .@Guillaume + "/10, C: " + .@Croix + "/10",1,0x006400; - end; - } - - // BG Variables - set $@FlaviusBG1, 1; - set $@FlaviusBG1_Victory, 0; - set .Guillaume_Score, 0; - set .Guillaume_Loss, 0; - set .Croix_Score, 0; - set .Croix_Loss, 0; - set .Match, 0; - // Prepare NPC - donpcevent "#gfl1_respawn::OnBGStart"; - donpcevent "#cfl1_respawn::OnBGStart"; - enablenpc "Therapist in battle#fl11"; - enablenpc "Therapist in battle#fl12"; - disablenpc "Guillaume Vintenar#fl1"; - disablenpc "Croix Vintenar#fl1"; - // Build and Warp Teams - donpcevent "Fl1R_Guillaume::OnEnterBG"; - donpcevent "Fl1R_Croix::OnEnterBG"; - announce "Battleground -- Flavius [80-99] has started!",0,0x006400; - initnpctimer; - // Start Match!! - -OnRoundStart: - sleep 2000; - if( $@FlaviusBG1 != 1 ) end; - - areapercentheal "bat_b01",382,2,397,17,100,100; - areapercentheal "bat_b01",2,282,17,297,100,100; - bg_warp $@FlaviusBG1_id1,"bat_b01",311,224; - bg_warp $@FlaviusBG1_id2,"bat_b01",87,75; - - sleep 2000; - if( $@FlaviusBG1 != 1 ) end; - - set .Match, .Match + 1; - // Crystal Spawn - set .Guillaume_Crystal, bg_monster($@FlaviusBG1_id1,"bat_b01",328,150,"Crystal Guillaume",1914,"Flavius_BG1::OnGuillaumeBreak"); - setcell "bat_b01",327,151,329,149,cell_basilica,1; - setcell "bat_b01",327,151,329,149,cell_walkable,1; - - set .Croix_Crystal, bg_monster($@FlaviusBG1_id2,"bat_b01",62,150,"Crystal Croix",1915,"Flavius_BG1::OnCroixBreak"); - setcell "bat_b01",62,149,60,151,cell_basilica,1; - setcell "bat_b01",62,149,60,151,cell_walkable,1; - - // Guardian Spawns - bg_monster $@FlaviusBG1_id1,"bat_b01",328,160,"Guillaume Guardian",1949,"Flavius_BG1::OnGuiGuardian"; - bg_monster $@FlaviusBG1_id1,"bat_b01",328,140,"Guillaume Guardian",1950,"Flavius_BG1::OnGuiGuardian"; - set .Guillaume_Guardian, 2; - bg_monster $@FlaviusBG1_id2,"bat_b01",62,160,"Croix Guardian",1949,"Flavius_BG1::OnCroGuardian"; - bg_monster $@FlaviusBG1_id2,"bat_b01",61,140,"Croix Guardian",1950,"Flavius_BG1::OnCroGuardian"; - set .Croix_Guardian, 2; - // Announces - mapannounce "bat_b01","The Battle of Flavius [ " + .Match + " ] Round has begun!!",1,0x006400; - end; - -OnRoundStop: - // Remove Monsters - killmonster "bat_b01","Flavius_BG1::OnGuiGuardian"; - killmonster "bat_b01","Flavius_BG1::OnCroGuardian"; - setcell "bat_b01",327,151,329,149,cell_walkable,0; - setcell "bat_b01",327,151,329,149,cell_basilica,0; - killmonster "bat_b01","Flavius_BG1::OnGuillaumeBreak"; - setcell "bat_b01",62,149,60,151,cell_walkable,0; - setcell "bat_b01",62,149,60,151,cell_basilica,0; - killmonster "bat_b01","Flavius_BG1::OnCroixBreak"; - end; - -OnGuiGuardian: - if( set(.Guillaume_Guardian, .Guillaume_Guardian - 1) <= 0 ) - { - setcell "bat_b01",327,151,329,149,cell_walkable,0; - setcell "bat_b01",327,151,329,149,cell_basilica,0; - mapannounce "bat_b01","The Guillaume Crystal is vulnerable to attack!",1,0x0000FF; - } - end; - -OnCroGuardian: - if( set(.Croix_Guardian, .Croix_Guardian - 1) <= 0 ) - { - setcell "bat_b01",62,149,60,151,cell_walkable,0; - setcell "bat_b01",62,149,60,151,cell_basilica,0; - mapannounce "bat_b01","The Croix Crystal is vulnerable to attack!",1,0xFF0000; - } - end; - -OnGuillaumeBreak: - donpcevent "Flavius_BG1::OnRoundStop"; - set .Guillaume_Loss, .Guillaume_Loss + 1; - if( set(.Croix_Score, .Croix_Score + 1) < 2 ) - { - bg_updatescore "bat_b01",.Guillaume_Score,.Croix_Score; - mapannounce "bat_b01","The Guillaume Crystal has been destroyed!",1,0x0000FF; - donpcevent "Flavius_BG1::OnRoundStart"; - } - else - { - bg_updatescore "bat_b01",.Guillaume_Score,.Croix_Score; - mapannounce "bat_b01","The Croix army has won the Battle of Flavius!",1,0xFF0000; - set $@FlaviusBG1_Victory, 2; - donpcevent "Flavius_BG1::OnMatchEnd"; - } - end; - -OnCroixBreak: - donpcevent "Flavius_BG1::OnRoundStop"; - set .Croix_Loss, .Croix_Loss + 1; - if( set(.Guillaume_Score, .Guillaume_Score + 1) < 2 ) - { - bg_updatescore "bat_b01",.Guillaume_Score,.Croix_Score; - mapannounce "bat_b01","The Croix Crystal has been destroyed!",1,0xFF0000; - donpcevent "Flavius_BG1::OnRoundStart"; - } - else - { - bg_updatescore "bat_b01",.Guillaume_Score,.Croix_Score; - mapannounce "bat_b01","The Guillaume army has won the Battle of Flavius!",1,0x0000FF; - set $@FlaviusBG1_Victory, 1; - donpcevent "Flavius_BG1::OnMatchEnd"; - } - end; - -OnTimer2400000: - mapannounce "bat_b01","Battle of Flavius will ends in 5 minutes",1,0x006400; - end; -OnTimer2640000: - mapannounce "bat_b01","Battle of Flavius will ends in 1 minute",1,0x006400; - end; - -OnTimer2700000: - if( .Croix_Score > .Guillaume_Score ) - { - mapannounce "bat_b01","The Croix army has won the Battle of Flavius!",1,0xFF0000; - set $@FlaviusBG1_Victory, 2; - } - else if( .Croix_Score < .Guillaume_Score ) - { - mapannounce "bat_b01","The Guillaume army has won the Battle of Flavius!",1,0x0000FF; - set $@FlaviusBG1_Victory, 1; - } - else - { - mapannounce "bat_b01","The Battle of Flavius is over. The time is out, this is a Tie",1,0x006400; - set $@FlaviusBG1_Victory, 3; - } - -OnMatchEnd: - set $@FlaviusBG1, 2; - stopnpctimer; - donpcevent "#gfl1_respawn::OnBGStop"; - donpcevent "#cfl1_respawn::OnBGStop"; - disablenpc "Therapist in battle#fl11"; - disablenpc "Therapist in battle#fl12"; - enablenpc "Guillaume Vintenar#fl1"; - enablenpc "Croix Vintenar#fl1"; - sleep 2000; - bg_warp $@FlaviusBG1_id1,"bat_b01",390,10; - bg_warp $@FlaviusBG1_id2,"bat_b01",10,290; - sleep 3000; - mapannounce "bat_b01","Battle of Flavius will close in 1 minute!",1,0x006400; - initnpctimer; - end; - -OnTimer30000: - if( $@FlaviusBG1 == 2 ) - mapannounce "bat_b01","Battle of Flavius will close in 30 seconds!",1,0x006400; - end; -OnTimer50000: - if( $@FlaviusBG1 == 2 ) - mapannounce "bat_b01","Battle of Flavius will close in 10 seconds!",1,0x006400; - end; - -OnTimer60000: - if( $@FlaviusBG1 != 2 ) - end; -OnReset: - stopnpctimer; - donpcevent "Flavius_BG1::OnRoundStop"; - set .Guillaume_Score, 0; - set .Guillaume_Crystal, 0; - set .Guillaume_Loss, 0; - set .Croix_Score, 0; - set .Croix_Crystal, 0; - set .Croix_Loss, 0; - set .Match, 0; - set $@FlaviusBG1_Victory, 0; - // NPC's - disablenpc "Guillaume Vintenar#fl1"; - disablenpc "Croix Vintenar#fl1"; - disablenpc "Therapist in battle#fl11"; - disablenpc "Therapist in battle#fl12"; - - if( $@FlaviusBG1_id1 ) { bg_destroy $@FlaviusBG1_id1; set $@FlaviusBG1_id1, 0; } - if( $@FlaviusBG1_id2 ) { bg_destroy $@FlaviusBG1_id2; set $@FlaviusBG1_id2, 0; } - sleep 1000; - mapwarp "bat_b01","bat_room",155,150; - sleep 2000; - maprespawnguildid "bat_b01",0,3; // Just in case someone else - sleep 2000; - bg_updatescore "bat_b01",0,0; - set $@FlaviusBG1, 0; - donpcevent "Flavius_BG1::OnReadyCheck"; - end; -} - -// Battleground rewards -// ********************************************************************* - -bat_b01,390,13,5 script Guillaume Vintenar#fl1 419,{ - if( $@FlaviusBG1_Victory ) - { - if( $@FlaviusBG1_Victory == Bat_Team ) - { // Victory - mes "[Swandery]"; - mes "Blessed Guillaume!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - set .@Reward, 9; - } - else - { // - mes "[Swandery]"; - mes "You lost, but you're dedicated to this battle."; - mes "This is a reward for your great dedication by Guillaume Marollo!"; - mes "Just take this defeat a lesson, and later you would definitely learn."; - close2; - set .@Reward, 3; - } - - setquest 2070; - getitem 7829, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} - -bat_b01,10,293,5 script Croix Vintenar#fl1 415,{ - if( $@FlaviusBG1_Victory ) - { - if( $@FlaviusBG1_Victory == Bat_Team ) - { // Victory - mes "[Swandery]"; - mes "Blessed Croax!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - set .@Reward, 9; - } - else - { // - mes "[Swandery]"; - mes "Oh, " + strcharinfo(0) + ". Don't be sad."; - mes "Even though we didn't win, we did our best."; - mes "This is a Royal gift from Croix, and please don't forget this battle. We can win the next."; - close2; - set .@Reward, 3; - } - - setquest 2070; - getitem 7829, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} - -// Battleground Therapist -// ********************************************************************* - -bat_b01,390,13,5 script Therapist in battle#fl12 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -bat_b01,10,293,5 script Therapist in battle#fl11 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -// Battleground Respawn -// ********************************************************************* - -bat_b01,390,10,0 script #gfl1_respawn 139,{ - end; - -OnBGStart: - initnpctimer; - end; - -OnBGStop: - stopnpctimer; - end; - -OnTimer24000: - misceffect EF_SANCTUARY; - end; - -OnTimer25000: - areapercentheal "bat_b01",382,2,397,17,100,100; - areawarp "bat_b01",382,2,397,17,"bat_b01",311,224; - initnpctimer; - end; -} - -bat_b01,10,290,0 script #cfl1_respawn 139,{ - end; - -OnBGStart: - initnpctimer; - end; - -OnBGStop: - stopnpctimer; - end; - -OnTimer24000: - misceffect EF_SANCTUARY; - end; - -OnTimer25000: - areapercentheal "bat_b01",2,282,17,297,100,100; - areawarp "bat_b01",2,282,17,297,"bat_b01",87,75; - initnpctimer; - end; -} - -// Flags -// ********************************************************************* - -bat_b01,304,231,1 duplicate(Guillaume camp#bat) Guillaume camp#bat1 973 -bat_b01,319,231,1 duplicate(Guillaume camp#bat) Guillaume camp#bat2 973 -bat_b01,304,218,1 duplicate(Guillaume camp#bat) Guillaume camp#bat3 973 -bat_b01,319,218,1 duplicate(Guillaume camp#bat) Guillaume camp#bat4 973 -bat_b01,304,231,1 duplicate(Guillaume camp#bat) Guillaume camp#bat5 973 -bat_b01,304,231,1 duplicate(Guillaume camp#bat) Guillaume camp#bat6 973 -bat_b01,335,142,1 duplicate(Guillaume camp#bat) Guillaume camp#bat7 973 -bat_b01,335,157,1 duplicate(Guillaume camp#bat) Guillaume camp#bat8 973 -bat_b01,390,16,1 duplicate(Guillaume camp#bat) Guillaume camp#bat9 973 -bat_b01,292,163,1 duplicate(Guillaume camp#bat) Guillaume camp#bat19 973 -bat_b01,292,136,1 duplicate(Guillaume camp#bat) Guillaume camp#bat20 973 -bat_b01,241,185,1 duplicate(Guillaume camp#bat) Guillaume camp#bat21 973 -bat_b01,247,179,1 duplicate(Guillaume camp#bat) Guillaume camp#bat22 973 - -bat_b01,96,81,1 duplicate(Croix camp#bat) Croix camp#bat1 974 -bat_b01,96,68,1 duplicate(Croix camp#bat) Croix camp#bat2 974 -bat_b01,79,81,1 duplicate(Croix camp#bat) Croix camp#bat3 974 -bat_b01,79,68,1 duplicate(Croix camp#bat) Croix camp#bat4 974 -bat_b01,96,81,1 duplicate(Croix camp#bat) Croix camp#bat5 974 -bat_b01,96,81,1 duplicate(Croix camp#bat) Croix camp#bat6 974 -bat_b01,59,164,1 duplicate(Croix camp#bat) Croix camp#bat7 974 -bat_b01,59,137,1 duplicate(Croix camp#bat) Croix camp#bat8 974 -bat_b01,10,296,1 duplicate(Croix camp#bat) Croix camp#bat9 974 -bat_b01,110,162,1 duplicate(Croix camp#bat) Croix camp#bat18 974 -bat_b01,110,137,1 duplicate(Croix camp#bat) Croix camp#bat19 974 -bat_b01,152,120,1 duplicate(Croix camp#bat) Croix camp#bat20 974 -bat_b01,158,114,1 duplicate(Croix camp#bat) Croix camp#bat21 974 diff --git a/npc/custom/battleground/unofficial/bg_flavius_02.txt b/npc/custom/battleground/unofficial/bg_flavius_02.txt deleted file mode 100644 index 889feb7ae3..0000000000 --- a/npc/custom/battleground/unofficial/bg_flavius_02.txt +++ /dev/null @@ -1,428 +0,0 @@ -// ============================================================================== -// BattleGround System - Flavius 2 -// ============================================================================== - -// Registration NPC's -// ********************************************************************* - -bat_room,142,227,4 script Registration::Fl2R_Guillaume 418,{ - end; -OnInit: - waitingroom "Battle Station 10 Players",10,"Flavius_BG2::OnGuillaumeJoin",1; - end; -OnEnterBG: - set $@FlaviusBG2_id1, waitingroom2bg("bat_b02",390,10,"Flavius_BG2::OnGuillaumeQuit",""); - end; -} - -bat_room,142,204,0 script Registration::Fl2R_Croix 414,{ - end; -OnInit: - waitingroom "Battle Station 10 Players",10,"Flavius_BG2::OnCroixJoin",1; - end; -OnEnterBG: - set $@FlaviusBG2_id2, waitingroom2bg("bat_b02",10,290,"Flavius_BG2::OnCroixQuit",""); - end; -} - -// Battleground Engine -// ********************************************************************* - -- script Flavius_BG2 -1,{ - end; - -OnInit: - disablenpc "Guillaume Vintenar#fl2"; - disablenpc "Croix Vintenar#fl2"; - disablenpc "Therapist in battle#fl21"; - disablenpc "Therapist in battle#fl22"; - end; - -OnGuillaumeQuit: -OnCroixQuit: - set BG_Delay_Tick, gettimetick(2) + 1200; - end; - -OnGuillaumeJoin: -OnCroixJoin: - if( $@FlaviusBG2 == 0 ) - donpcevent "Flavius_BG2::OnReadyCheck"; - end; - -OnReadyCheck: - if( $@FlaviusBG2 ) - end; - set .@Guillaume, getwaitingroomstate(0,"Fl2R_Guillaume"); - set .@Croix, getwaitingroomstate(0,"Fl2R_Croix"); - - if( .@Guillaume < 10 || .@Croix < 10 ) - { - mapannounce "bat_room","Battleground -- Flavius [80-99] G: " + .@Guillaume + "/10, C: " + .@Croix + "/10",1,0x808000; - end; - } - - // BG Variables - set $@FlaviusBG2, 1; - set $@FlaviusBG2_Victory, 0; - set .Guillaume_Score, 0; - set .Guillaume_Loss, 0; - set .Croix_Score, 0; - set .Croix_Loss, 0; - set .Match, 0; - // Prepare NPC - donpcevent "#gfl2_respawn::OnBGStart"; - donpcevent "#cfl2_respawn::OnBGStart"; - enablenpc "Therapist in battle#fl21"; - enablenpc "Therapist in battle#fl22"; - disablenpc "Guillaume Vintenar#fl2"; - disablenpc "Croix Vintenar#fl2"; - // Build and Warp Teams - donpcevent "Fl2R_Guillaume::OnEnterBG"; - donpcevent "Fl2R_Croix::OnEnterBG"; - announce "Battleground -- Flavius [80-99] has started!",0,0x808000; - initnpctimer; - // Start Match!! - -OnRoundStart: - sleep 2000; - if( $@FlaviusBG2 != 1 ) end; - - areapercentheal "bat_b02",382,2,397,17,100,100; - areapercentheal "bat_b02",2,282,17,297,100,100; - bg_warp $@FlaviusBG2_id1,"bat_b02",311,224; - bg_warp $@FlaviusBG2_id2,"bat_b02",87,75; - - sleep 2000; - if( $@FlaviusBG2 != 1 ) end; - - set .Match, .Match + 1; - // Crystal Spawn - set .Guillaume_Crystal, bg_monster($@FlaviusBG2_id1,"bat_b02",328,150,"Crystal Guillaume",1914,"Flavius_BG2::OnGuillaumeBreak"); - setcell "bat_b02",327,151,329,149,cell_basilica,1; - setcell "bat_b02",327,151,329,149,cell_walkable,1; - - set .Croix_Crystal, bg_monster($@FlaviusBG2_id2,"bat_b02",62,150,"Crystal Croix",1915,"Flavius_BG2::OnCroixBreak"); - setcell "bat_b02",62,149,60,151,cell_basilica,1; - setcell "bat_b02",62,149,60,151,cell_walkable,1; - - // Guardian Spawns - bg_monster $@FlaviusBG2_id1,"bat_b02",328,160,"Guillaume Guardian",1949,"Flavius_BG2::OnGuiGuardian"; - bg_monster $@FlaviusBG2_id1,"bat_b02",328,140,"Guillaume Guardian",1950,"Flavius_BG2::OnGuiGuardian"; - set .Guillaume_Guardian, 2; - bg_monster $@FlaviusBG2_id2,"bat_b02",62,160,"Croix Guardian",1949,"Flavius_BG2::OnCroGuardian"; - bg_monster $@FlaviusBG2_id2,"bat_b02",61,140,"Croix Guardian",1950,"Flavius_BG2::OnCroGuardian"; - set .Croix_Guardian, 2; - // Announces - mapannounce "bat_b02","The Battle of Flavius [ " + .Match + " ] Round has begun!!",1,0x808000; - end; - -OnRoundStop: - // Remove Monsters - killmonster "bat_b02","Flavius_BG2::OnGuiGuardian"; - killmonster "bat_b02","Flavius_BG2::OnCroGuardian"; - setcell "bat_b02",327,151,329,149,cell_walkable,0; - setcell "bat_b02",327,151,329,149,cell_basilica,0; - killmonster "bat_b02","Flavius_BG2::OnGuillaumeBreak"; - setcell "bat_b02",62,149,60,151,cell_walkable,0; - setcell "bat_b02",62,149,60,151,cell_basilica,0; - killmonster "bat_b02","Flavius_BG2::OnCroixBreak"; - end; - -OnGuiGuardian: - if( set(.Guillaume_Guardian, .Guillaume_Guardian - 1) <= 0 ) - { - setcell "bat_b02",327,151,329,149,cell_walkable,0; - setcell "bat_b02",327,151,329,149,cell_basilica,0; - mapannounce "bat_b02","The Guillaume Crystal is vulnerable to attack!",1,0x0000FF; - } - end; - -OnCroGuardian: - if( set(.Croix_Guardian, .Croix_Guardian - 1) <= 0 ) - { - setcell "bat_b02",62,149,60,151,cell_walkable,0; - setcell "bat_b02",62,149,60,151,cell_basilica,0; - mapannounce "bat_b02","The Croix Crystal is vulnerable to attack!",1,0xFF0000; - } - end; - -OnGuillaumeBreak: - donpcevent "Flavius_BG2::OnRoundStop"; - set .Guillaume_Loss, .Guillaume_Loss + 1; - if( set(.Croix_Score, .Croix_Score + 1) < 2 ) - { - bg_updatescore "bat_b02",.Guillaume_Score,.Croix_Score; - mapannounce "bat_b02","The Guillaume Crystal has been destroyed!",1,0x0000FF; - donpcevent "Flavius_BG2::OnRoundStart"; - } - else - { - bg_updatescore "bat_b02",.Guillaume_Score,.Croix_Score; - mapannounce "bat_b02","The Croix army has won the Battle of Flavius!",1,0xFF0000; - set $@FlaviusBG2_Victory, 2; - donpcevent "Flavius_BG2::OnMatchEnd"; - } - end; - -OnCroixBreak: - donpcevent "Flavius_BG2::OnRoundStop"; - set .Croix_Loss, .Croix_Loss + 1; - if( set(.Guillaume_Score, .Guillaume_Score + 1) < 2 ) - { - bg_updatescore "bat_b02",.Guillaume_Score,.Croix_Score; - mapannounce "bat_b02","The Croix Crystal has been destroyed!",1,0xFF0000; - donpcevent "Flavius_BG2::OnRoundStart"; - } - else - { - bg_updatescore "bat_b02",.Guillaume_Score,.Croix_Score; - mapannounce "bat_b02","The Guillaume army has won the Battle of Flavius!",1,0x0000FF; - set $@FlaviusBG2_Victory, 1; - donpcevent "Flavius_BG2::OnMatchEnd"; - } - end; - -OnTimer2400000: - mapannounce "bat_b02","Battle of Flavius will ends in 5 minutes",1,0x808000; - end; -OnTimer2640000: - mapannounce "bat_b02","Battle of Flavius will ends in 1 minute",1,0x808000; - end; - -OnTimer2700000: - if( .Croix_Score > .Guillaume_Score ) - { - mapannounce "bat_b02","The Croix army has won the Battle of Flavius!",1,0xFF0000; - set $@FlaviusBG2_Victory, 2; - } - else if( .Croix_Score < .Guillaume_Score ) - { - mapannounce "bat_b02","The Guillaume army has won the Battle of Flavius!",1,0x0000FF; - set $@FlaviusBG2_Victory, 1; - } - else - { - mapannounce "bat_b02","The Battle of Flavius is over. The time is out, this is a Tie",1,0x808000; - set $@FlaviusBG2_Victory, 3; - } - -OnMatchEnd: - set $@FlaviusBG2, 2; - stopnpctimer; - donpcevent "#gfl2_respawn::OnBGStop"; - donpcevent "#cfl2_respawn::OnBGStop"; - disablenpc "Therapist in battle#fl21"; - disablenpc "Therapist in battle#fl22"; - enablenpc "Guillaume Vintenar#fl2"; - enablenpc "Croix Vintenar#fl2"; - sleep 2000; - bg_warp $@FlaviusBG2_id1,"bat_b02",390,10; - bg_warp $@FlaviusBG2_id2,"bat_b02",10,290; - sleep 3000; - mapannounce "bat_b02","Battle of Flavius will close in 1 minute!",1,0x808000; - initnpctimer; - end; - -OnTimer30000: - if( $@FlaviusBG2 == 2 ) - mapannounce "bat_b02","Battle of Flavius will close in 30 seconds!",1,0x808000; - end; -OnTimer50000: - if( $@FlaviusBG2 == 2 ) - mapannounce "bat_b02","Battle of Flavius will close in 10 seconds!",1,0x808000; - end; - -OnTimer60000: - if( $@FlaviusBG2 != 2 ) - end; -OnReset: - stopnpctimer; - donpcevent "Flavius_BG2::OnRoundStop"; - set .Guillaume_Score, 0; - set .Guillaume_Crystal, 0; - set .Guillaume_Loss, 0; - set .Croix_Score, 0; - set .Croix_Crystal, 0; - set .Croix_Loss, 0; - set .Match, 0; - set $@FlaviusBG2_Victory, 0; - // NPC's - disablenpc "Guillaume Vintenar#fl2"; - disablenpc "Croix Vintenar#fl2"; - disablenpc "Therapist in battle#fl21"; - disablenpc "Therapist in battle#fl22"; - - if( $@FlaviusBG2_id1 ) { bg_destroy $@FlaviusBG2_id1; set $@FlaviusBG2_id1, 0; } - if( $@FlaviusBG2_id2 ) { bg_destroy $@FlaviusBG2_id2; set $@FlaviusBG2_id2, 0; } - sleep 1000; - mapwarp "bat_b02","bat_room",155,150; - sleep 2000; - maprespawnguildid "bat_b02",0,3; // Just in case someone else - sleep 2000; - bg_updatescore "bat_b02",0,0; - set $@FlaviusBG2, 0; - donpcevent "Flavius_BG2::OnReadyCheck"; - end; -} - -// Battleground rewards -// ********************************************************************* - -bat_b02,390,13,5 script Guillaume Vintenar#fl2 419,{ - if( $@FlaviusBG2_Victory ) - { - if( $@FlaviusBG2_Victory == Bat_Team ) - { // Victory - mes "[Swandery]"; - mes "Blessed Guillaume!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - set .@Reward, 9; - } - else - { // - mes "[Swandery]"; - mes "You lost, but you're dedicated to this battle."; - mes "This is a reward for your great dedication by Guillaume Marollo!"; - mes "Just take this defeat a lesson, and later you would definitely learn."; - close2; - set .@Reward, 3; - } - - setquest 2070; - getitem 7829, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} - -bat_b02,10,293,5 script Croix Vintenar#fl2 415,{ - if( $@FlaviusBG2_Victory ) - { - if( $@FlaviusBG2_Victory == Bat_Team ) - { // Victory - mes "[Swandery]"; - mes "Blessed Croax!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - set .@Reward, 9; - } - else - { // - mes "[Swandery]"; - mes "Oh, " + strcharinfo(0) + ". Don't be sad."; - mes "Even though we didn't win, we did our best."; - mes "This is a Royal gift from Croix, and please don't forget this battle. We can win the next."; - close2; - set .@Reward, 3; - } - - setquest 2070; - getitem 7829, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} - -// Battleground Therapist -// ********************************************************************* - -bat_b02,390,13,5 script Therapist in battle#fl22 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -bat_b02,10,293,5 script Therapist in battle#fl21 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -// Battleground Respawn -// ********************************************************************* - -bat_b02,390,10,0 script #gfl2_respawn 139,{ - end; - -OnBGStart: - initnpctimer; - end; - -OnBGStop: - stopnpctimer; - end; - -OnTimer24000: - misceffect EF_SANCTUARY; - end; - -OnTimer25000: - areapercentheal "bat_b02",382,2,397,17,100,100; - areawarp "bat_b02",382,2,397,17,"bat_b02",311,224; - initnpctimer; - end; -} - -bat_b02,10,290,0 script #cfl2_respawn 139,{ - end; - -OnBGStart: - initnpctimer; - end; - -OnBGStop: - stopnpctimer; - end; - -OnTimer24000: - misceffect EF_SANCTUARY; - end; - -OnTimer25000: - areapercentheal "bat_b02",2,282,17,297,100,100; - areawarp "bat_b02",2,282,17,297,"bat_b02",87,75; - initnpctimer; - end; -} - -// Flags -// ********************************************************************* - -bat_b02,304,231,1 duplicate(Guillaume camp#bat) Guillaume camp#bat32 973 -bat_b02,319,231,1 duplicate(Guillaume camp#bat) Guillaume camp#bat33 973 -bat_b02,304,218,1 duplicate(Guillaume camp#bat) Guillaume camp#bat34 973 -bat_b02,319,218,1 duplicate(Guillaume camp#bat) Guillaume camp#bat35 973 -bat_b02,304,231,1 duplicate(Guillaume camp#bat) Guillaume camp#bat36 973 -bat_b02,304,231,1 duplicate(Guillaume camp#bat) Guillaume camp#bat37 973 -bat_b02,335,142,1 duplicate(Guillaume camp#bat) Guillaume camp#bat38 973 -bat_b02,335,157,1 duplicate(Guillaume camp#bat) Guillaume camp#bat39 973 -bat_b02,390,16,1 duplicate(Guillaume camp#bat) Guillaume camp#bat40 973 -bat_b02,292,163,1 duplicate(Guillaume camp#bat) Guillaume camp#bat41 973 -bat_b02,292,136,1 duplicate(Guillaume camp#bat) Guillaume camp#bat42 973 -bat_b02,241,185,1 duplicate(Guillaume camp#bat) Guillaume camp#bat43 973 -bat_b02,247,179,1 duplicate(Guillaume camp#bat) Guillaume camp#bat44 973 - -bat_b02,96,81,1 duplicate(Croix camp#bat) Croix camp#bat30 974 -bat_b02,96,68,1 duplicate(Croix camp#bat) Croix camp#bat31 974 -bat_b02,79,81,1 duplicate(Croix camp#bat) Croix camp#bat32 974 -bat_b02,79,68,1 duplicate(Croix camp#bat) Croix camp#bat33 974 -bat_b02,96,81,1 duplicate(Croix camp#bat) Croix camp#bat34 974 -bat_b02,96,81,1 duplicate(Croix camp#bat) Croix camp#bat35 974 -bat_b02,59,164,1 duplicate(Croix camp#bat) Croix camp#bat36 974 -bat_b02,59,137,1 duplicate(Croix camp#bat) Croix camp#bat37 974 -bat_b02,10,296,1 duplicate(Croix camp#bat) Croix camp#bat38 974 -bat_b02,110,162,1 duplicate(Croix camp#bat) Croix camp#bat39 974 -bat_b02,110,137,1 duplicate(Croix camp#bat) Croix camp#bat40 974 -bat_b02,152,120,1 duplicate(Croix camp#bat) Croix camp#bat41 974 -bat_b02,158,114,1 duplicate(Croix camp#bat) Croix camp#bat42 974 diff --git a/npc/custom/battleground/unofficial/bg_kvm01.txt b/npc/custom/battleground/unofficial/bg_kvm01.txt deleted file mode 100644 index 84dd6e210d..0000000000 --- a/npc/custom/battleground/unofficial/bg_kvm01.txt +++ /dev/null @@ -1,378 +0,0 @@ -// ============================================================================== -// BattleGround System - KvM 80~99 -// ============================================================================== - -// Registration NPC's -// ********************************************************************* - -bat_room,253,227,4 script Registration::KvM01R_Guillaume 418,{ // KvM Guillaume - end; - -OnInit: - waitingroom "Battle Station 5 Players",5,"KvM01_BG::OnGuillaumeJoin",1; - end; - -OnEnterBG: - set $@KvM01BG_id1, waitingroom2bg("bat_c01",53,128,"KvM01_BG::OnGuillaumeQuit","KvM01_BG::OnGuillaumeDie"); - end; -} - -bat_room,253,204,0 script Registration::KvM01R_Croix 414,{ // KvM Croix - end; - -OnInit: - waitingroom "Battle Station 5 Players",5,"KvM01_BG::OnCroixJoin",1; - end; - -OnEnterBG: - set $@KvM01BG_id2, waitingroom2bg("bat_c01",146,55,"KvM01_BG::OnCroixQuit","KvM01_BG::OnCroixDie"); - end; -} - -// Light Effects -// ********************************************************************* - -bat_c01,54,123,0 script #bat_c01a 111,{ - end; - -OnKvM01LightA: specialeffect EF_BEGINSPELL2; end; -OnKvM01LightB: specialeffect EF_BEGINSPELL3; end; -OnKvM01LightC: specialeffect EF_BEGINSPELL4; end; -} - -bat_c01,56,125,0 duplicate(#bat_c01a) #bat_c01b 111 -bat_c01,58,127,0 duplicate(#bat_c01a) #bat_c01c 111 -bat_c01,141,56,0 duplicate(#bat_c01a) #bat_c01d 111 -bat_c01,143,58,0 duplicate(#bat_c01a) #bat_c01e 111 -bat_c01,145,60,0 duplicate(#bat_c01a) #bat_c01f 111 - -// Battleground Engine -// ********************************************************************* - -- script KvM01_BG -1,{ - end; - -OnInit: - setwall "bat_c01",54,122,6,7,0,"batc01wall_a"; - setwall "bat_c01",55,122,5,7,0,"batc01wall_b"; - setwall "bat_c01",140,56,6,7,0,"batc01wall_c"; - setwall "bat_c01",140,57,5,7,0,"batc01wall_d"; - disablenpc "TherapistKvM01a"; - disablenpc "TherapistKvM01b"; - disablenpc "VintenarKvM01a"; - disablenpc "VintenarKvM01b"; - end; - -OnGuillaumeJoin: -OnCroixJoin: - donpcevent "KvM01_BG::OnReadyCheck"; - end; - -OnGuillaumeQuit: - set BG_Delay_Tick, gettimetick(2) + 1200; -OnGuillaumeDie: - if( $@KvM01BG == 2 ) - { - set .Guillaume_Count, .Guillaume_Count - 1; - set .Croix_Score, .Croix_Score + 1; - bg_updatescore "bat_c01",.Guillaume_Score,.Croix_Score; - if( .Guillaume_Count < 1 ) donpcevent "KvM01_BG::OnCroixWin"; - } - end; - -OnCroixQuit: - set BG_Delay_Tick, gettimetick(2) + 1200; -OnCroixDie: - if( $@KvM01BG == 2 ) - { - set .Croix_Count, .Croix_Count - 1; - set .Guillaume_Score, .Guillaume_Score + 1; - bg_updatescore "bat_c01",.Guillaume_Score,.Croix_Score; - if( .Croix_Count < 1 ) donpcevent "KvM01_BG::OnGuillaumeWin"; - } - end; - -OnReadyCheck: - if( $@KvM01BG ) - end; - set .@Guillaume, getwaitingroomstate(0,"KvM01R_Guillaume"); - set .@Croix, getwaitingroomstate(0,"KvM01R_Croix"); - - if( .@Guillaume < 5 || .@Croix < 5 ) - { - if( .@Guillaume > 3 && .@Croix > 3 && !agitcheck() && !agitcheck2() && $@KvM_Flood < gettimetick(2) ) - { - announce "Battleground -- Kreiger Von Midgard [80-99] G: " + .@Guillaume + "/5, C: " + .@Croix + "/5",0,0x696969; - set $@KvM_Flood, gettimetick(2) + 15; - } - else - mapannounce "bat_room","Battleground -- Kreiger Von Midgard [80-99] G: " + .@Guillaume + "/5, C: " + .@Croix + "/5",1,0x696969; - end; - } - - set $@KvM01BG, 1; // Starting - donpcevent "KvM01R_Croix::OnEnterBG"; - donpcevent "KvM01R_Guillaume::OnEnterBG"; - donpcevent "KvM01_BG::OnStart"; - end; - -OnStart: - announce "Battleground -- Kreiger Von Midgard [80-99] has started!",0,0x696969; - enablenpc "TherapistKvM01a"; - enablenpc "TherapistKvM01b"; - disablenpc "VintenarKvM01a"; - disablenpc "VintenarKvM01b"; - set $@KvM01BG_Victory, 0; - sleep 2000; - // Warp Teams - bg_warp $@KvM01BG_id1,"bat_c01",53,128; - bg_warp $@KvM01BG_id2,"bat_c01",146,55; - // ScoreBoard - set .Guillaume_Score, 0; - set .Croix_Score, 0; - initnpctimer; - end; - -OnTimer5000: - areapercentheal "bat_c01",50,123,58,131,100,100; - areapercentheal "bat_c01",141,52,149,60,100,100; - mapannounce "bat_c01","The Battle will start in 25 seconds!!",1,0x696969; - end; - -OnTimer26000: - mapannounce "bat_c01","The Battle will start in 4 seconds!!",1,0x696969; - end; - -OnTimer27000: - donpcevent "::OnKvM01LightA"; - end; - -OnTimer28000: - donpcevent "::OnKvM01LightB"; - end; - -OnTimer29000: - donpcevent "::OnKvM01LightC"; - end; - -OnTimer30000: - // Team Members - set .Guillaume_Count, bg_get_data($@KvM01BG_id1, 0); - set .Croix_Count, bg_get_data($@KvM01BG_id2, 0); - if( .Guillaume_Count < 5 || .Croix_Count < 5 ) - { - set $@KvM01BG_Victory, 3; - set $@KvM01BG, 3; - mapannounce "bat_c01","There are not enough players to start the battle",1,0x696969; - stopnpctimer; - sleep 2000; - donpcevent "KvM01_BG::OnStop"; - end; - } - - set $@KvM01BG, 2; // Playing - areapercentheal "bat_c01",50,123,58,131,100,100; - bg_warp $@KvM01BG_id1,"bat_c01",62,119; - areapercentheal "bat_c01",141,52,149,60,100,100; - bg_warp $@KvM01BG_id2,"bat_c01",137,64; - end; - -OnTimer32000: - mapannounce "bat_c01","The Battle of Kreiger Von Midgard has begun!!",1,0x696969; - end; - -OnTimer300000: - mapannounce "bat_c01","The Battle will ends in 30 seconds!!",1,0x696969; - end; - -OnTimer330000: - if( .Croix_Count > .Guillaume_Count ) - donpcevent "KvM01_BG::OnCroixWin"; - else if( .Croix_Count < .Guillaume_Count ) - donpcevent "KvM01_BG::OnGuillaumeWin"; - else - { // Draw Game - set $@KvM01BG, 3; - set $@KvM01BG_Victory, 3; - - stopnpctimer; - sleep 2000; - mapannounce "bat_c01","The time is out! This is a Tie...",1,0x696969; - donpcevent "KvM01_BG::OnStop"; - } - end; - -OnGuillaumeWin: - set $@KvM01BG, 3; - set $@KvM01BG_Victory, 1; - - stopnpctimer; - sleep 2000; - mapannounce "bat_c01","The Guillaume Army has won the Battle of Kreiger Von Midgard",1,0x0000FF; - donpcevent "KvM01_BG::OnStop"; - end; - -OnCroixWin: - set $@KvM01BG, 3; - set $@KvM01BG_Victory, 2; - - stopnpctimer; - sleep 2000; - mapannounce "bat_c01","The Croix Army has won the Battle of Kreiger Von Midgard",1,0xFF0000; - donpcevent "KvM01_BG::OnStop"; - end; - -OnStop: - disablenpc "TherapistKvM01a"; - disablenpc "TherapistKvM01b"; - enablenpc "VintenarKvM01a"; - enablenpc "VintenarKvM01b"; - // Warp Teams - bg_warp $@KvM01BG_id1,"bat_c01",53,128; - bg_warp $@KvM01BG_id2,"bat_c01",146,55; - donpcevent "KvM01_BG_Out::OnBegin"; - end; - -OnReset: - stopnpctimer; - stopnpctimer "KvM01_BG_Out"; - set .Croix_Count, 0; - set .Guillaume_Count, 0; - set .Croix_Score, 0; - set .Guillaume_Score, 0; - set $@KvM01BG_Victory, 0; - if( $@KvM01BG_id1 ) { bg_destroy $@KvM01BG_id1; set $@KvM01BG_id1, 0; } - if( $@KvM01BG_id2 ) { bg_destroy $@KvM01BG_id2; set $@KvM01BG_id2, 0; } - disablenpc "TherapistKvM01a"; - disablenpc "TherapistKvM01b"; - disablenpc "VintenarKvM01a"; - disablenpc "VintenarKvM01b"; - sleep 1000; - mapwarp "bat_c01","bat_room",155,150; - sleep 2000; - maprespawnguildid "bat_c01",0,3; // Just in case someone else - bg_updatescore "bat_c01",0,0; - sleep 2000; - set $@KvM01BG, 0; - donpcevent "KvM01_BG::OnReadyCheck"; // Maybe a game is ready to start - end; -} - -- script KvM01_BG_Out -1,{ - end; - -OnBegin: - initnpctimer; - end; - -OnTimer3000: - mapannounce "bat_c01","Battle of Kreiger Von Midgard will close in 1 minute!",1,0x696969; - end; -OnTimer30000: - mapannounce "bat_c01","Battle of Kreiger Von Midgard will close in 30 seconds!",1,0x696969; - end; -OnTimer50000: - mapannounce "bat_c01","Battle of Kreiger Von Midgard will close in 10 seconds!",1,0x696969; - end; -OnTimer60000: - donpcevent "KvM01_BG::OnReset"; - end; -} - -// Battleground Therapist -// ********************************************************************* - -bat_c01,51,130,5 script Therapist in battle::TherapistKvM01a 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -bat_c01,148,53,1 script Therapist in battle::TherapistKvM01b 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -// Battleground rewards -// ********************************************************************* - -bat_c01,51,130,5 script Guillaume Vintenar::VintenarKvM01a 419,{ - if( $@KvM01BG_Victory ) - { - if( $@KvM01BG_Victory == 3 ) - { - setquest 6025; - bg_leave; - warp "bat_room",155,150; - end; - } - else if( $@KvM01BG_Victory == Bat_Team ) - { // Victory - set .@Reward, 5; - mes "[Swandery]"; - mes "Blessed Guillaume!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - } - else - { // - set .@Reward, 1; - mes "[Swandery]"; - mes "You lost, but you're dedicated to this battle."; - mes "This is a reward for your great dedication by Guillaume Marollo!"; - mes "Just take this defeat a lesson, and later you would definitely learn."; - close2; - } - - setquest 6025; - getitem 6376, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} - -bat_c01,148,53,1 script Croix Vintenar::VintenarKvM01b 415,{ - if( $@KvM01BG_Victory ) - { - if( $@KvM01BG_Victory == 3 ) - { - setquest 6025; - bg_leave; - warp "bat_room",155,150; - end; - } - else if( $@KvM01BG_Victory == Bat_Team ) - { // Victory - set .@Reward, 5; - mes "[Swandery]"; - mes "Blessed Croax!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - } - else - { // - set .@Reward, 1; - mes "[Swandery]"; - mes "Oh, " + strcharinfo(0) + ". Don't be sad."; - mes "Even though we didn't win, we did our best."; - mes "This is a Royal gift from Croix, and please don't forget this battle. We can win the next."; - close2; - } - - setquest 6025; - getitem 6376, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} diff --git a/npc/custom/battleground/unofficial/bg_kvm02.txt b/npc/custom/battleground/unofficial/bg_kvm02.txt deleted file mode 100644 index db789f58fd..0000000000 --- a/npc/custom/battleground/unofficial/bg_kvm02.txt +++ /dev/null @@ -1,378 +0,0 @@ -// ============================================================================== -// BattleGround System - KvM 60~79 -// ============================================================================== - -// Registration NPC's -// ********************************************************************* - -bat_room,225,227,4 script Registration::KvM02R_Guillaume 418,{ // KvM Guillaume - end; - -OnInit: - waitingroom "Battle Station 5 Players",5,"KvM02_BG::OnGuillaumeJoin",1; - end; - -OnEnterBG: - set $@KvM02BG_id1, waitingroom2bg("bat_c02",53,128,"KvM02_BG::OnGuillaumeQuit","KvM02_BG::OnGuillaumeDie"); - end; -} - -bat_room,225,204,0 script Registration::KvM02R_Croix 414,{ // KvM Croix - end; - -OnInit: - waitingroom "Battle Station 5 Players",5,"KvM02_BG::OnCroixJoin",1; - end; - -OnEnterBG: - set $@KvM02BG_id2, waitingroom2bg("bat_c02",146,55,"KvM02_BG::OnCroixQuit","KvM02_BG::OnCroixDie"); - end; -} - -// Light Effects -// ********************************************************************* - -bat_c02,54,123,0 script #bat_c02a 111,{ - end; - -OnKvM02LightA: specialeffect EF_BEGINSPELL2; end; -OnKvM02LightB: specialeffect EF_BEGINSPELL3; end; -OnKvM02LightC: specialeffect EF_BEGINSPELL4; end; -} - -bat_c02,56,125,0 duplicate(#bat_c02a) #bat_c02b 111 -bat_c02,58,127,0 duplicate(#bat_c02a) #bat_c02c 111 -bat_c02,141,56,0 duplicate(#bat_c02a) #bat_c02d 111 -bat_c02,143,58,0 duplicate(#bat_c02a) #bat_c02e 111 -bat_c02,145,60,0 duplicate(#bat_c02a) #bat_c02f 111 - -// Battleground Engine -// ********************************************************************* - -- script KvM02_BG -1,{ - end; - -OnInit: - setwall "bat_c02",54,122,6,7,0,"batc02wall_a"; - setwall "bat_c02",55,122,5,7,0,"batc02wall_b"; - setwall "bat_c02",140,56,6,7,0,"batc02wall_c"; - setwall "bat_c02",140,57,5,7,0,"batc02wall_d"; - disablenpc "TherapistKvM02a"; - disablenpc "TherapistKvM02b"; - disablenpc "VintenarKvM02a"; - disablenpc "VintenarKvM02b"; - end; - -OnGuillaumeJoin: -OnCroixJoin: - donpcevent "KvM02_BG::OnReadyCheck"; - end; - -OnGuillaumeQuit: - set BG_Delay_Tick, gettimetick(2) + 1200; -OnGuillaumeDie: - if( $@KvM02BG == 2 ) - { - set .Guillaume_Count, .Guillaume_Count - 1; - set .Croix_Score, .Croix_Score + 1; - bg_updatescore "bat_c02",.Guillaume_Score,.Croix_Score; - if( .Guillaume_Count < 1 ) donpcevent "KvM02_BG::OnCroixWin"; - } - end; - -OnCroixQuit: - set BG_Delay_Tick, gettimetick(2) + 1200; -OnCroixDie: - if( $@KvM02BG == 2 ) - { - set .Croix_Count, .Croix_Count - 1; - set .Guillaume_Score, .Guillaume_Score + 1; - bg_updatescore "bat_c02",.Guillaume_Score,.Croix_Score; - if( .Croix_Count < 1 ) donpcevent "KvM02_BG::OnGuillaumeWin"; - } - end; - -OnReadyCheck: - if( $@KvM02BG ) - end; - set .@Guillaume, getwaitingroomstate(0,"KvM02R_Guillaume"); - set .@Croix, getwaitingroomstate(0,"KvM02R_Croix"); - - if( .@Guillaume < 5 || .@Croix < 5 ) - { - if( .@Guillaume > 3 && .@Croix > 3 && !agitcheck() && !agitcheck2() && $@KvM_Flood < gettimetick(2) ) - { - announce "Battleground -- Kreiger Von Midgard [60-79] G: " + .@Guillaume + "/5, C: " + .@Croix + "/5",0,0x808080; - set $@KvM_Flood, gettimetick(2) + 15; - } - else - mapannounce "bat_room","Battleground -- Kreiger Von Midgard [60-79] G: " + .@Guillaume + "/5, C: " + .@Croix + "/5",1,0x808080; - end; - } - - set $@KvM02BG, 1; // Starting - donpcevent "KvM02R_Croix::OnEnterBG"; - donpcevent "KvM02R_Guillaume::OnEnterBG"; - donpcevent "KvM02_BG::OnStart"; - end; - -OnStart: - announce "Battleground -- Kreiger Von Midgard [60-79] has started!",0,0x808080; - enablenpc "TherapistKvM02a"; - enablenpc "TherapistKvM02b"; - disablenpc "VintenarKvM02a"; - disablenpc "VintenarKvM02b"; - set $@KvM02BG_Victory, 0; - sleep 2000; - // Warp Teams - bg_warp $@KvM02BG_id1,"bat_c02",53,128; - bg_warp $@KvM02BG_id2,"bat_c02",146,55; - // ScoreBoard - set .Guillaume_Score, 0; - set .Croix_Score, 0; - initnpctimer; - end; - -OnTimer5000: - areapercentheal "bat_c02",50,123,58,131,100,100; - areapercentheal "bat_c02",141,52,149,60,100,100; - mapannounce "bat_c02","The Battle will start in 25 seconds!!",1,0x808080; - end; - -OnTimer26000: - mapannounce "bat_c02","The Battle will start in 4 seconds!!",1,0x808080; - end; - -OnTimer27000: - donpcevent "::OnKvM02LightA"; - end; - -OnTimer28000: - donpcevent "::OnKvM02LightB"; - end; - -OnTimer29000: - donpcevent "::OnKvM02LightC"; - end; - -OnTimer30000: - // Team Members - set .Guillaume_Count, bg_get_data($@KvM02BG_id1, 0); - set .Croix_Count, bg_get_data($@KvM02BG_id2, 0); - if( .Guillaume_Count < 5 || .Croix_Count < 5 ) - { - set $@KvM02BG_Victory, 3; - set $@KvM02BG, 3; - mapannounce "bat_c02","There are not enough players to start the battle",1,0x808080; - stopnpctimer; - sleep 2000; - donpcevent "KvM02_BG::OnStop"; - end; - } - - set $@KvM02BG, 2; // Playing - areapercentheal "bat_c02",50,123,58,131,100,100; - bg_warp $@KvM02BG_id1,"bat_c02",62,119; - areapercentheal "bat_c02",141,52,149,60,100,100; - bg_warp $@KvM02BG_id2,"bat_c02",137,64; - end; - -OnTimer32000: - mapannounce "bat_c02","The Battle of Kreiger Von Midgard has begun!!",1,0x808080; - end; - -OnTimer300000: - mapannounce "bat_c02","The Battle will ends in 30 seconds!!",1,0x808080; - end; - -OnTimer330000: - if( .Croix_Count > .Guillaume_Count ) - donpcevent "KvM02_BG::OnCroixWin"; - else if( .Croix_Count < .Guillaume_Count ) - donpcevent "KvM02_BG::OnGuillaumeWin"; - else - { // Draw Game - set $@KvM02BG, 3; - set $@KvM02BG_Victory, 3; - - stopnpctimer; - sleep 2000; - mapannounce "bat_c02","The time is out! This is a Tie...",1,0x808080; - donpcevent "KvM02_BG::OnStop"; - } - end; - -OnGuillaumeWin: - set $@KvM02BG, 3; - set $@KvM02BG_Victory, 1; - - stopnpctimer; - sleep 2000; - mapannounce "bat_c02","The Guillaume Army has won the Battle of Kreiger Von Midgard",1,0x0000FF; - donpcevent "KvM02_BG::OnStop"; - end; - -OnCroixWin: - set $@KvM02BG, 3; - set $@KvM02BG_Victory, 2; - - stopnpctimer; - sleep 2000; - mapannounce "bat_c02","The Croix Army has won the Battle of Kreiger Von Midgard",1,0xFF0000; - donpcevent "KvM02_BG::OnStop"; - end; - -OnStop: - disablenpc "TherapistKvM02a"; - disablenpc "TherapistKvM02b"; - enablenpc "VintenarKvM02a"; - enablenpc "VintenarKvM02b"; - // Warp Teams - bg_warp $@KvM02BG_id1,"bat_c02",53,128; - bg_warp $@KvM02BG_id2,"bat_c02",146,55; - donpcevent "KvM02_BG_Out::OnBegin"; - end; - -OnReset: - stopnpctimer; - stopnpctimer "KvM02_BG_Out"; - set .Croix_Count, 0; - set .Guillaume_Count, 0; - set .Croix_Score, 0; - set .Guillaume_Score, 0; - set $@KvM02BG_Victory, 0; - if( $@KvM02BG_id1 ) { bg_destroy $@KvM02BG_id1; set $@KvM02BG_id1, 0; } - if( $@KvM02BG_id2 ) { bg_destroy $@KvM02BG_id2; set $@KvM02BG_id2, 0; } - disablenpc "TherapistKvM02a"; - disablenpc "TherapistKvM02b"; - disablenpc "VintenarKvM02a"; - disablenpc "VintenarKvM02b"; - sleep 1000; - mapwarp "bat_c02","bat_room",155,150; - sleep 2000; - maprespawnguildid "bat_c02",0,3; // Just in case someone else - bg_updatescore "bat_c02",0,0; - sleep 2000; - set $@KvM02BG, 0; - donpcevent "KvM02_BG::OnReadyCheck"; // Maybe a game is ready to start - end; -} - -- script KvM02_BG_Out -1,{ - end; - -OnBegin: - initnpctimer; - end; - -OnTimer3000: - mapannounce "bat_c02","Battle of Kreiger Von Midgard will close in 1 minute!",1,0x808080; - end; -OnTimer30000: - mapannounce "bat_c02","Battle of Kreiger Von Midgard will close in 30 seconds!",1,0x808080; - end; -OnTimer50000: - mapannounce "bat_c02","Battle of Kreiger Von Midgard will close in 10 seconds!",1,0x808080; - end; -OnTimer60000: - donpcevent "KvM02_BG::OnReset"; - end; -} - -// Battleground Therapist -// ********************************************************************* - -bat_c02,51,130,5 script Therapist in battle::TherapistKvM02a 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -bat_c02,148,53,1 script Therapist in battle::TherapistKvM02b 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -// Battleground rewards -// ********************************************************************* - -bat_c02,51,130,5 script Guillaume Vintenar::VintenarKvM02a 419,{ - if( $@KvM02BG_Victory ) - { - if( $@KvM02BG_Victory == 3 ) - { - setquest 6025; - bg_leave; - warp "bat_room",155,150; - end; - } - else if( $@KvM02BG_Victory == Bat_Team ) - { // Victory - set .@Reward, 3; - mes "[Swandery]"; - mes "Blessed Guillaume!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - } - else - { // - set .@Reward, 1; - mes "[Swandery]"; - mes "You lost, but you're dedicated to this battle."; - mes "This is a reward for your great dedication by Guillaume Marollo!"; - mes "Just take this defeat a lesson, and later you would definitely learn."; - close2; - } - - setquest 6025; - getitem 6376, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} - -bat_c02,148,53,1 script Croix Vintenar::VintenarKvM02b 415,{ - if( $@KvM02BG_Victory ) - { - if( $@KvM02BG_Victory == 3 ) - { - setquest 6025; - bg_leave; - warp "bat_room",155,150; - end; - } - else if( $@KvM02BG_Victory == Bat_Team ) - { // Victory - set .@Reward, 3; - mes "[Swandery]"; - mes "Blessed Croax!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - } - else - { // - set .@Reward, 1; - mes "[Swandery]"; - mes "Oh, " + strcharinfo(0) + ". Don't be sad."; - mes "Even though we didn't win, we did our best."; - mes "This is a Royal gift from Croix, and please don't forget this battle. We can win the next."; - close2; - } - - setquest 6025; - getitem 6376, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} diff --git a/npc/custom/battleground/unofficial/bg_kvm03.txt b/npc/custom/battleground/unofficial/bg_kvm03.txt deleted file mode 100644 index b0174efe10..0000000000 --- a/npc/custom/battleground/unofficial/bg_kvm03.txt +++ /dev/null @@ -1,378 +0,0 @@ -// ============================================================================== -// BattleGround System - KvM 1~59 -// ============================================================================== - -// Registration NPC's -// ********************************************************************* - -bat_room,197,227,4 script Registration::KvM03R_Guillaume 418,{ // KvM Guillaume - end; - -OnInit: - waitingroom "Battle Station 5 Players",5,"KvM03_BG::OnGuillaumeJoin",1; - end; - -OnEnterBG: - set $@KvM03BG_id1, waitingroom2bg("bat_c03",53,128,"KvM03_BG::OnGuillaumeQuit","KvM03_BG::OnGuillaumeDie"); - end; -} - -bat_room,197,204,0 script Registration::KvM03R_Croix 414,{ // KvM Croix - end; - -OnInit: - waitingroom "Battle Station 5 Players",5,"KvM03_BG::OnCroixJoin",1; - end; - -OnEnterBG: - set $@KvM03BG_id2, waitingroom2bg("bat_c03",146,55,"KvM03_BG::OnCroixQuit","KvM03_BG::OnCroixDie"); - end; -} - -// Light Effects -// ********************************************************************* - -bat_c03,54,123,0 script #bat_c03a 111,{ - end; - -OnKvM03LightA: specialeffect EF_BEGINSPELL2; end; -OnKvM03LightB: specialeffect EF_BEGINSPELL3; end; -OnKvM03LightC: specialeffect EF_BEGINSPELL4; end; -} - -bat_c03,56,125,0 duplicate(#bat_c03a) #bat_c03b 111 -bat_c03,58,127,0 duplicate(#bat_c03a) #bat_c03c 111 -bat_c03,141,56,0 duplicate(#bat_c03a) #bat_c03d 111 -bat_c03,143,58,0 duplicate(#bat_c03a) #bat_c03e 111 -bat_c03,145,60,0 duplicate(#bat_c03a) #bat_c03f 111 - -// Battleground Engine -// ********************************************************************* - -- script KvM03_BG -1,{ - end; - -OnInit: - setwall "bat_c03",54,122,6,7,0,"batc03wall_a"; - setwall "bat_c03",55,122,5,7,0,"batc03wall_b"; - setwall "bat_c03",140,56,6,7,0,"batc03wall_c"; - setwall "bat_c03",140,57,5,7,0,"batc03wall_d"; - disablenpc "TherapistKvM03a"; - disablenpc "TherapistKvM03b"; - disablenpc "VintenarKvM03a"; - disablenpc "VintenarKvM03b"; - end; - -OnGuillaumeJoin: -OnCroixJoin: - donpcevent "KvM03_BG::OnReadyCheck"; - end; - -OnGuillaumeQuit: - set BG_Delay_Tick, gettimetick(2) + 1200; -OnGuillaumeDie: - if( $@KvM03BG == 2 ) - { - set .Guillaume_Count, .Guillaume_Count - 1; - set .Croix_Score, .Croix_Score + 1; - bg_updatescore "bat_c03",.Guillaume_Score,.Croix_Score; - if( .Guillaume_Count < 1 ) donpcevent "KvM03_BG::OnCroixWin"; - } - end; - -OnCroixQuit: - set BG_Delay_Tick, gettimetick(2) + 1200; -OnCroixDie: - if( $@KvM03BG == 2 ) - { - set .Croix_Count, .Croix_Count - 1; - set .Guillaume_Score, .Guillaume_Score + 1; - bg_updatescore "bat_c03",.Guillaume_Score,.Croix_Score; - if( .Croix_Count < 1 ) donpcevent "KvM03_BG::OnGuillaumeWin"; - } - end; - -OnReadyCheck: - if( $@KvM03BG ) - end; - set .@Guillaume, getwaitingroomstate(0,"KvM03R_Guillaume"); - set .@Croix, getwaitingroomstate(0,"KvM03R_Croix"); - - if( .@Guillaume < 5 || .@Croix < 5 ) - { - if( .@Guillaume > 3 && .@Croix > 3 && !agitcheck() && !agitcheck2() && $@KvM_Flood < gettimetick(2) ) - { - announce "Battleground -- Kreiger Von Midgard [1-59] G: " + .@Guillaume + "/5, C: " + .@Croix + "/5",0,0xC0C0C0; - set $@KvM_Flood, gettimetick(2) + 15; - } - else - mapannounce "bat_room","Battleground -- Kreiger Von Midgard [1-59] G: " + .@Guillaume + "/5, C: " + .@Croix + "/5",1,0xC0C0C0; - end; - } - - set $@KvM03BG, 1; // Starting - donpcevent "KvM03R_Croix::OnEnterBG"; - donpcevent "KvM03R_Guillaume::OnEnterBG"; - donpcevent "KvM03_BG::OnStart"; - end; - -OnStart: - announce "Battleground -- Kreiger Von Midgard [1-59] has started!",0,0xC0C0C0; - enablenpc "TherapistKvM03a"; - enablenpc "TherapistKvM03b"; - disablenpc "VintenarKvM03a"; - disablenpc "VintenarKvM03b"; - set $@KvM03BG_Victory, 0; - sleep 2000; - // Warp Teams - bg_warp $@KvM03BG_id1,"bat_c03",53,128; - bg_warp $@KvM03BG_id2,"bat_c03",146,55; - // ScoreBoard - set .Guillaume_Score, 0; - set .Croix_Score, 0; - initnpctimer; - end; - -OnTimer5000: - areapercentheal "bat_c03",50,123,58,131,100,100; - areapercentheal "bat_c03",141,52,149,60,100,100; - mapannounce "bat_c03","The Battle will start in 25 seconds!!",1,0xC0C0C0; - end; - -OnTimer26000: - mapannounce "bat_c03","The Battle will start in 4 seconds!!",1,0xC0C0C0; - end; - -OnTimer27000: - donpcevent "::OnKvM03LightA"; - end; - -OnTimer28000: - donpcevent "::OnKvM03LightB"; - end; - -OnTimer29000: - donpcevent "::OnKvM03LightC"; - end; - -OnTimer30000: - // Team Members - set .Guillaume_Count, bg_get_data($@KvM03BG_id1, 0); - set .Croix_Count, bg_get_data($@KvM03BG_id2, 0); - if( .Guillaume_Count < 5 || .Croix_Count < 5 ) - { - set $@KvM03BG_Victory, 3; - set $@KvM03BG, 3; - mapannounce "bat_c03","There are not enough players to start the battle",1,0xC0C0C0; - stopnpctimer; - sleep 2000; - donpcevent "KvM03_BG::OnStop"; - end; - } - - set $@KvM03BG, 2; // Playing - areapercentheal "bat_c03",50,123,58,131,100,100; - bg_warp $@KvM03BG_id1,"bat_c03",62,119; - areapercentheal "bat_c03",141,52,149,60,100,100; - bg_warp $@KvM03BG_id2,"bat_c03",137,64; - end; - -OnTimer32000: - mapannounce "bat_c03","The Battle of Kreiger Von Midgard has begun!!",1,0xC0C0C0; - end; - -OnTimer300000: - mapannounce "bat_c03","The Battle will ends in 30 seconds!!",1,0xC0C0C0; - end; - -OnTimer330000: - if( .Croix_Count > .Guillaume_Count ) - donpcevent "KvM03_BG::OnCroixWin"; - else if( .Croix_Count < .Guillaume_Count ) - donpcevent "KvM03_BG::OnGuillaumeWin"; - else - { // Draw Game - set $@KvM03BG, 3; - set $@KvM03BG_Victory, 3; - - stopnpctimer; - sleep 2000; - mapannounce "bat_c03","The time is out! This is a Tie...",1,0xC0C0C0; - donpcevent "KvM03_BG::OnStop"; - } - end; - -OnGuillaumeWin: - set $@KvM03BG, 3; - set $@KvM03BG_Victory, 1; - - stopnpctimer; - sleep 2000; - mapannounce "bat_c03","The Guillaume Army has won the Battle of Kreiger Von Midgard",1,0x0000FF; - donpcevent "KvM03_BG::OnStop"; - end; - -OnCroixWin: - set $@KvM03BG, 3; - set $@KvM03BG_Victory, 2; - - stopnpctimer; - sleep 2000; - mapannounce "bat_c03","The Croix Army has won the Battle of Kreiger Von Midgard",1,0xFF0000; - donpcevent "KvM03_BG::OnStop"; - end; - -OnStop: - disablenpc "TherapistKvM03a"; - disablenpc "TherapistKvM03b"; - enablenpc "VintenarKvM03a"; - enablenpc "VintenarKvM03b"; - // Warp Teams - bg_warp $@KvM03BG_id1,"bat_c03",53,128; - bg_warp $@KvM03BG_id2,"bat_c03",146,55; - donpcevent "KvM03_BG_Out::OnBegin"; - end; - -OnReset: - stopnpctimer; - stopnpctimer "KvM03_BG_Out"; - set .Croix_Count, 0; - set .Guillaume_Count, 0; - set .Croix_Score, 0; - set .Guillaume_Score, 0; - set $@KvM03BG_Victory, 0; - if( $@KvM03BG_id1 ) { bg_destroy $@KvM03BG_id1; set $@KvM03BG_id1, 0; } - if( $@KvM03BG_id2 ) { bg_destroy $@KvM03BG_id2; set $@KvM03BG_id2, 0; } - disablenpc "TherapistKvM03a"; - disablenpc "TherapistKvM03b"; - disablenpc "VintenarKvM03a"; - disablenpc "VintenarKvM03b"; - sleep 1000; - mapwarp "bat_c03","bat_room",155,150; - sleep 2000; - maprespawnguildid "bat_c03",0,3; // Just in case someone else - bg_updatescore "bat_c03",0,0; - sleep 2000; - set $@KvM03BG, 0; - donpcevent "KvM03_BG::OnReadyCheck"; // Maybe a game is ready to start - end; -} - -- script KvM03_BG_Out -1,{ - end; - -OnBegin: - initnpctimer; - end; - -OnTimer3000: - mapannounce "bat_c03","Battle of Kreiger Von Midgard will close in 1 minute!",1,0xC0C0C0; - end; -OnTimer30000: - mapannounce "bat_c03","Battle of Kreiger Von Midgard will close in 30 seconds!",1,0xC0C0C0; - end; -OnTimer50000: - mapannounce "bat_c03","Battle of Kreiger Von Midgard will close in 10 seconds!",1,0xC0C0C0; - end; -OnTimer60000: - donpcevent "KvM03_BG::OnReset"; - end; -} - -// Battleground Therapist -// ********************************************************************* - -bat_c03,51,130,5 script Therapist in battle::TherapistKvM03a 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -bat_c03,148,53,1 script Therapist in battle::TherapistKvM03b 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -// Battleground rewards -// ********************************************************************* - -bat_c03,51,130,5 script Guillaume Vintenar::VintenarKvM03a 419,{ - if( $@KvM03BG_Victory ) - { - if( $@KvM03BG_Victory == 3 ) - { - setquest 6025; - bg_leave; - warp "bat_room",155,150; - end; - } - else if( $@KvM03BG_Victory == Bat_Team ) - { // Victory - set .@Reward, 1; - mes "[Swandery]"; - mes "Blessed Guillaume!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - } - else - { // - set .@Reward, 0; - mes "[Swandery]"; - mes "You lost, but you're dedicated to this battle."; - mes "This is a reward for your great dedication by Guillaume Marollo!"; - mes "Just take this defeat a lesson, and later you would definitely learn."; - close2; - } - - setquest 6025; - getitem 6376, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} - -bat_c03,148,53,1 script Croix Vintenar::VintenarKvM03b 415,{ - if( $@KvM03BG_Victory ) - { - if( $@KvM03BG_Victory == 3 ) - { - setquest 6025; - bg_leave; - warp "bat_room",155,150; - end; - } - else if( $@KvM03BG_Victory == Bat_Team ) - { // Victory - set .@Reward, 1; - mes "[Swandery]"; - mes "Blessed Croax!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - } - else - { // - set .@Reward, 0; - mes "[Swandery]"; - mes "Oh, " + strcharinfo(0) + ". Don't be sad."; - mes "Even though we didn't win, we did our best."; - mes "Please don't forget this battle. We can win the next."; - close2; - } - - setquest 6025; - getitem 6376, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} diff --git a/npc/custom/battleground/unofficial/bg_tierra_01.txt b/npc/custom/battleground/unofficial/bg_tierra_01.txt deleted file mode 100644 index 3d8102b539..0000000000 --- a/npc/custom/battleground/unofficial/bg_tierra_01.txt +++ /dev/null @@ -1,476 +0,0 @@ -// ============================================================================== -// BattleGround System - Tierra Valley 1 -// ============================================================================== - -// Registration NPC's -// ********************************************************************* - -bat_room,58,227,4 script Registration::TV1R_Guillaume 418,{ - end; -OnInit: - waitingroom "Battle Station 10 Players",10,"Tierra_BG1::OnGuillaumeJoin",1; - end; -OnEnterBG: - set $@TierraBG1_id1, waitingroom2bg("bat_a01",50,374,"Tierra_BG1::OnGuillaumeQuit",""); - end; -} - -bat_room,58,204,0 script Registration::TV1R_Croix 414,{ - end; -OnInit: - waitingroom "Battle Station 10 Players",10,"Tierra_BG1::OnCroixJoin",1; - end; -OnEnterBG: - set $@TierraBG1_id2, waitingroom2bg("bat_a01",42,16,"Tierra_BG1::OnCroixQuit",""); - end; -} - -// Battleground Engine -// ********************************************************************* - -- script Tierra_BG1 -1,{ - end; - -OnInit: - disablenpc "Croix Vintenar#tv1"; - disablenpc "Guillaume Vintenar#tv1"; - disablenpc "Therapist in battle#tv11"; - disablenpc "Therapist in battle#tv12"; - end; - -OnGuillaumeQuit: -OnCroixQuit: - set BG_Delay_Tick, gettimetick(2) + 1200; - end; - -OnGuillaumeJoin: -OnCroixJoin: - if( $@TierraBG1 == 0 ) - donpcevent "Tierra_BG1::OnReadyCheck"; - end; - -OnReadyCheck: - if( $@TierraBG1 ) - end; - set .@Guillaume, getwaitingroomstate(0,"TV1R_Guillaume"); - set .@Croix, getwaitingroomstate(0,"TV1R_Croix"); - - if( .@Guillaume < 10 || .@Croix < 10 ) - { - mapannounce "bat_room","Battleground -- Tierra Valley [80-99] G: " + .@Guillaume + "/10, C: " + .@Croix + "/10",1,0xFFA500; - end; - } - - set $@TierraBG1, 1; - donpcevent "TV1R_Croix::OnEnterBG"; - donpcevent "TV1R_Guillaume::OnEnterBG"; - donpcevent "Guillaume_TV1B::OnBuild"; - donpcevent "Croix_TV1B::OnBuild"; - bg_monster $@TierraBG1_id1,"bat_a01",176,345,"Food Depot",1909,"Tierra_BG1::OnGuillaumeBreak"; - bg_monster $@TierraBG1_id2,"bat_a01",167,50,"Food Storage",1910,"Tierra_BG1::OnCroixBreak"; - bg_monster 0,"bat_a01",273,204,"Neutrality Flag",1911,"Tierra_BG1::OnNeutralBreak"; - - set .Neutral_Base, 0; - set $@TierraBG1_Victory, 0; - - set .Guardian_1, 0; - set .Guardian_2, 0; - set .Guardian_3, 0; - - enablenpc "Therapist in battle#tv11"; - enablenpc "Therapist in battle#tv12"; - disablenpc "Croix Vintenar#tv1"; - disablenpc "Guillaume Vintenar#tv1"; - // Respawner - donpcevent "#gtv1_respawn::OnBGStart"; - donpcevent "#ctv1_respawn::OnBGStart"; - donpcevent "#ntv1_respawn::OnBGStart"; - // Warp Teams - announce "Battleground -- Tierra Valley [80-99] has started!",0,0xFFA500; - bg_warp $@TierraBG1_id1,"bat_a01",353,344; - bg_warp $@TierraBG1_id2,"bat_a01",353,52; - // Final Messages - sleep 6000; - mapannounce "bat_a01","Guillaume Vintenar Axl Rose : Let's attack to burn down Croix's food storage",1,0x0000FF; - sleep 2000; - mapannounce "bat_a01","Croix Vintenar Swandery : Master of Valhalla! Let us be gifted with unfailing faith and courage",1,0xFF0000; - - initnpctimer; - end; - -OnNeutralBreak: - if( getcharid(4) == $@TierraBG1_id1 ) - { - mapannounce "bat_a01","Guillaume obtained a neurality banner, so they have an advantage.",1,0x0000FF; - bg_team_setxy $@TierraBG1_id2,42,16; - areawarp "bat_a01",52,208,61,217,"bat_a01",42,16; - } - else if( getcharid(4) == $@TierraBG1_id2 ) - { - mapannounce "bat_a01","Croix obtained a neutrality banner, so they have an advantage.",1,0xFF0000; - bg_team_setxy $@TierraBG1_id1,50,374; - areawarp "bat_a01",52,208,61,217,"bat_a01",50,374; - } - else end; - - set .Neutral_Base, getcharid(4); - bg_team_setxy .Neutral_Base,56,212; - - if( .Guardian_1 == 0 ) - set .Guardian_1, bg_monster(.Neutral_Base,"bat_a01",280,233,"Guardian",1949,"Tierra_BG1::OnGuardian1"); - else - bg_monster_set_team .Guardian_1, .Neutral_Base; - - if( .Guardian_2 == 0 ) - set .Guardian_2, bg_monster(.Neutral_Base,"bat_a01",287,203,"Guardian",1950,"Tierra_BG1::OnGuardian2"); - else - bg_monster_set_team .Guardian_2, .Neutral_Base; - - if( .Guardian_3 == 0 ) - set .Guardian_3, bg_monster(.Neutral_Base,"bat_a01",268,204,"Guardian",1949,"Tierra_BG1::OnGuardian3"); - else - bg_monster_set_team .Guardian_3, .Neutral_Base; - - sleep 10000; - if( $@TierraBG1 != 1 ) end; - - if( .Neutral_Base == $@TierraBG1_id1 ) - bg_monster .Neutral_Base,"bat_a01",273,204,"Guillaume Flag",1912,"Tierra_BG1::OnNeutralBreak"; - else if( .Neutral_Base == $@TierraBG1_id2 ) - bg_monster .Neutral_Base,"bat_a01",273,204,"Croix Flag",1913,"Tierra_BG1::OnNeutralBreak"; - end; - -OnGuardian1: set .Guardian_1, 0; end; -OnGuardian2: set .Guardian_2, 0; end; -OnGuardian3: set .Guardian_3, 0; end; - -OnGuillaumeBreak: - set $@TierraBG1_Victory, 2; - mapannounce "bat_a01","Croix Vintenar Swandery: We destroyed Guillaume's food storehouse. We won that! Wow!",1,0xFF0000; - donpcevent "Tierra_BG1::OnStop"; - end; - -OnCroixBreak: - set $@TierraBG1_Victory, 1; - mapannounce "bat_a01","Guillaume Vintenar Axl Rose: We destroyed Croix's food storehouse. We won that! Wow!",1,0x0000FF; - donpcevent "Tierra_BG1::OnStop"; - end; - -OnTimer2400000: - mapannounce "bat_a01","Battle of Tierra Gorge will ends in 5 minutes",1,0xFFA500; - end; -OnTimer2640000: - mapannounce "bat_a01","Battle of Tierra Gorge will ends in 1 minute",1,0xFFA500; - end; - -OnTimer2700000: - set $@TierraBG1_Victory, 3; // Draw Game - mapannounce "bat_a01","Battle of Tierra Gorge is over. The time is out, this is a Tie",1,0xFFA500; - donpcevent "Tierra_BG1::OnStop"; - end; - -OnStop: - set $@TierraBG1, 2; - disablenpc "Therapist in battle#tv11"; - disablenpc "Therapist in battle#tv12"; - donpcevent "#gtv1_respawn::OnBGStop"; - donpcevent "#ctv1_respawn::OnBGStop"; - donpcevent "#ntv1_respawn::OnBGStop"; - enablenpc "Croix Vintenar#tv1"; - enablenpc "Guillaume Vintenar#tv1"; - killmonster "bat_a01","Tierra_BG1::OnGuillaumeBreak"; - killmonster "bat_a01","Tierra_BG1::OnCroixBreak"; - killmonster "bat_a01","Tierra_BG1::OnNeutralBreak"; - killmonster "bat_a01","Tierra_BG1::OnGuardian1"; - killmonster "bat_a01","Tierra_BG1::OnGuardian2"; - killmonster "bat_a01","Tierra_BG1::OnGuardian3"; - stopnpctimer; - sleep 3000; - bg_warp $@TierraBG1_id1,"bat_a01",50,374; - bg_warp $@TierraBG1_id2,"bat_a01",42,16; - sleep 3000; - mapannounce "bat_a01","Battle of Tierra Gorge will close in 1 minute!",1,0xFFA500; - initnpctimer; - end; - -OnTimer30000: - if( $@TierraBG1 == 2 ) - mapannounce "bat_a01","Battle of Tierra Valley will close in 30 seconds!",1,0xFFA500; - end; -OnTimer50000: - if( $@TierraBG1 == 2 ) - mapannounce "bat_a01","Battle of Tierra Valley will close in 10 seconds!",1,0xFFA500; - end; - -OnTimer60000: - if( $@TierraBG1 != 2 ) - end; -OnReset: - stopnpctimer; - set .Neutral_Base, 0; - disablenpc "Croix Vintenar#tv1"; - disablenpc "Guillaume Vintenar#tv1"; - disablenpc "Therapist in battle#tv11"; - disablenpc "Therapist in battle#tv12"; - donpcevent "#gtv1_respawn::OnBGStop"; - donpcevent "#ctv1_respawn::OnBGStop"; - donpcevent "#ntv1_respawn::OnBGStop"; - - killmonster "bat_a01","Tierra_BG1::OnGuillaumeBreak"; - killmonster "bat_a01","Tierra_BG1::OnCroixBreak"; - killmonster "bat_a01","Tierra_BG1::OnNeutralBreak"; - killmonster "bat_a01","Tierra_BG1::OnGuardian1"; - killmonster "bat_a01","Tierra_BG1::OnGuardian2"; - killmonster "bat_a01","Tierra_BG1::OnGuardian3"; - donpcevent "Guillaume_TV1B::OnDestroy"; - donpcevent "Croix_TV1B::OnDestroy"; - - set $@TierraBG1_Victory, 0; - if( $@TierraBG1_id1 ) { bg_destroy $@TierraBG1_id1; set $@TierraBG1_id1, 0; } - if( $@TierraBG1_id2 ) { bg_destroy $@TierraBG1_id2; set $@TierraBG1_id2, 0; } - sleep 1000; - mapwarp "bat_a01","bat_room",155,150; - sleep 2000; - maprespawnguildid "bat_a01",0,3; // Just in case someone else - sleep 2000; - set $@TierraBG1, 0; - donpcevent "Tierra_BG1::OnReadyCheck"; // Maybe a game is ready to start - end; -} - -// Other Flags -// ********************************************************************* - -bat_a01,148,85,1 duplicate(Croix camp#bat) Croix camp#bat10 974 -bat_a01,155,85,1 duplicate(Croix camp#bat) Croix camp#bat11 974 -bat_a01,357,75,1 duplicate(Croix camp#bat) Croix camp#bat12 974 -bat_a01,348,74,1 duplicate(Croix camp#bat) Croix camp#bat13 974 -bat_a01,199,49,1 duplicate(Croix camp#bat) Croix camp#bat14 974 -bat_a01,168,16,1 duplicate(Croix camp#bat) Croix camp#bat15 974 -bat_a01,138,12,1 duplicate(Croix camp#bat) Croix camp#bat16 974 -bat_a01,108,35,1 duplicate(Croix camp#bat) Croix camp#bat17 974 -bat_a01,164,308,1 duplicate(Guillaume camp#bat) Guillaume camp#bat10 973 -bat_a01,157,308,1 duplicate(Guillaume camp#bat) Guillaume camp#bat11 973 -bat_a01,359,327,1 duplicate(Guillaume camp#bat) Guillaume camp#bat12 973 -bat_a01,350,326,1 duplicate(Guillaume camp#bat) Guillaume camp#bat13 973 -bat_a01,209,344,1 duplicate(Guillaume camp#bat) Guillaume camp#bat14 973 -bat_a01,173,380,1 duplicate(Guillaume camp#bat) Guillaume camp#bat15 973 -bat_a01,150,380,1 duplicate(Guillaume camp#bat) Guillaume camp#bat16 973 -bat_a01,118,357,1 duplicate(Guillaume camp#bat) Guillaume camp#bat17 973 -bat_a01,119,336,1 duplicate(Guillaume camp#bat) Guillaume camp#bat18 973 - -// Barricades -// ********************************************************************* - -- script Guillaume_TV1B -1,{ - end; - -OnBuild: - for( set .@i, 0; .@i < 16; set .@i, .@i + 1 ) - bg_monster 0,"bat_a01",170+.@i,130,"Barricade",1906,"Guillaume_TV1B::OnWall"; - - setwall "bat_a01",170,130,16,6,1,"bat_a01_g1"; - set .MyMobCount,16; - end; - -OnDestroy: - killmonster "bat_a01","Guillaume_TV1B::OnWall"; - if (checkwall("bat_a01_g1") == true) - delwall "bat_a01_g1"; - set .MyMobCount,0; - end; - -OnWall: - if( set(.MyMobCount,.MyMobCount - 1) < 1 ) - { - delwall "bat_a01_g1"; - mapannounce "bat_a01","South Gate : The Gate has been Destroy!!",1,0xFFA500; - } - end; -} - -- script Croix_TV1B -1,{ - end; - -OnBuild: - for( set .@i, 0; .@i < 16; set .@i, .@i + 1 ) - bg_monster 0,"bat_a01",186+.@i,266,"Barricade",1906,"Croix_TV1B::OnWall"; - - setwall "bat_a01",186,266,16,6,1,"bat_a01_c1"; - set .MyMobCount,16; - end; - -OnDestroy: - killmonster "bat_a01","Croix_TV1B::OnWall"; - delwall "bat_a01_c1"; - set .MyMobCount,0; - end; - -OnWall: - if( set(.MyMobCount,.MyMobCount - 1) < 1 ) - { - delwall "bat_a01_c1"; - mapannounce "bat_a01","North Gate : A Gate has been Destroy!!",1,0xFFA500; - } - end; -} - -// Battleground rewards -// ********************************************************************* - -bat_a01,45,19,3 script Croix Vintenar#tv1 415,{ - if( $@TierraBG1_Victory ) - { - if( $@TierraBG1_Victory == Bat_Team ) - { // Victory - set .@Reward, 3; - mes "[Swandery]"; - mes "Blessed Croax!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - } - else - { // - set .@Reward, 1; - mes "[Swandery]"; - mes "Oh, " + strcharinfo(0) + ". Don't be sad."; - mes "Even though we didn't win, we did our best."; - mes "This is a Royal gift from Croix, and please don't forget this battle. We can win the next."; - close2; - } - - setquest 2069; - getitem 7828, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} - -bat_a01,53,377,3 script Guillaume Vintenar#tv1 419,{ - if( $@TierraBG1_Victory ) - { - if( $@TierraBG1_Victory == Bat_Team ) - { // Victory - set .@Reward, 3; - mes "[Swandery]"; - mes "Blessed Guillaume!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - } - else - { // - set .@Reward, 1; - mes "[Swandery]"; - mes "You lost, but you're dedicated to this battle."; - mes "This is a reward for your great dedication by Guillaume Marollo!"; - mes "Just take this defeat a lesson, and later you would definitely learn."; - close2; - } - - setquest 2069; - getitem 7828, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} - -// Battleground Therapist -// ********************************************************************* - -bat_a01,60,216,3 script Ghost#tv13 950,{ - mes "[Ghost in valley]"; - mes "Boo...Boo..."; - specialeffect2 EF_HEAL; - close; -} - -bat_a01,53,377,3 script Therapist in battle#tv12 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -bat_a01,45,18,3 script Therapist in battle#tv11 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -// Battleground Respawn -// ********************************************************************* - -bat_a01,57,213,0 script #ntv1_respawn 139,{ - end; - -OnBGStart: - initnpctimer; - end; - -OnBGStop: - stopnpctimer; - end; - -OnTimer19000: - misceffect EF_SANCTUARY; - end; - -OnTimer20000: - areapercentheal "bat_a01",52,208,61,217,100,100; - areawarp "bat_a01",52,208,61,217,"bat_a01",301,208; - initnpctimer; - end; -} - -bat_a01,50,374,0 script #gtv1_respawn 139,{ - end; - -OnBGStart: - initnpctimer; - end; - -OnBGStop: - stopnpctimer; - end; - -OnTimer24000: - misceffect EF_SANCTUARY; - end; - -OnTimer25000: - areapercentheal "bat_a01",46,370,54,378,100,100; - areawarp "bat_a01",46,370,54,378,"bat_a01",354,340; - initnpctimer; - end; -} - -bat_a01,42,16,0 script #ctv1_respawn 139,{ - end; - -OnBGStart: - initnpctimer; - end; - -OnBGStop: - stopnpctimer; - end; - -OnTimer24000: - misceffect EF_SANCTUARY; - end; - -OnTimer25000: - areapercentheal "bat_a01",38,12,47,21,100,100; - areawarp "bat_a01",38,12,47,21,"bat_a01",354,57; - initnpctimer; - end; -} diff --git a/npc/custom/battleground/unofficial/bg_tierra_02.txt b/npc/custom/battleground/unofficial/bg_tierra_02.txt deleted file mode 100644 index 6aec5608f3..0000000000 --- a/npc/custom/battleground/unofficial/bg_tierra_02.txt +++ /dev/null @@ -1,476 +0,0 @@ -// ============================================================================== -// BattleGround System - Tierra Valley 2 -// ============================================================================== - -// Registration NPC's -// ********************************************************************* - -bat_room,114,227,4 script Registration::TV2R_Guillaume 418,{ - end; -OnInit: - waitingroom "Battle Station 10 Players",10,"Tierra_BG2::OnGuillaumeJoin",1; - end; -OnEnterBG: - set $@TierraBG2_id1, waitingroom2bg("bat_a02",50,374,"Tierra_BG2::OnGuillaumeQuit",""); - end; -} - -bat_room,114,204,0 script Registration::TV2R_Croix 414,{ - end; -OnInit: - waitingroom "Battle Station 10 Players",10,"Tierra_BG2::OnCroixJoin",1; - end; -OnEnterBG: - set $@TierraBG2_id2, waitingroom2bg("bat_a02",42,16,"Tierra_BG2::OnCroixQuit",""); - end; -} - -// Battleground Engine -// ********************************************************************* - -- script Tierra_BG2 -1,{ - end; - -OnInit: - disablenpc "Croix Vintenar#tv2"; - disablenpc "Guillaume Vintenar#tv2"; - disablenpc "Therapist in battle#tv21"; - disablenpc "Therapist in battle#tv22"; - end; - -OnGuillaumeQuit: -OnCroixQuit: - set BG_Delay_Tick, gettimetick(2) + 1200; - end; - -OnGuillaumeJoin: -OnCroixJoin: - if( $@TierraBG2 == 0 ) - donpcevent "Tierra_BG2::OnReadyCheck"; - end; - -OnReadyCheck: - if( $@TierraBG2 ) - end; - set .@Guillaume, getwaitingroomstate(0,"TV2R_Guillaume"); - set .@Croix, getwaitingroomstate(0,"TV2R_Croix"); - - if( .@Guillaume < 10 || .@Croix < 10 ) - { - mapannounce "bat_room","Battleground -- Tierra Valley [80-99] G: " + .@Guillaume + "/10, C: " + .@Croix + "/10",1,0xF4A460; - end; - } - - set $@TierraBG2, 1; - donpcevent "TV2R_Croix::OnEnterBG"; - donpcevent "TV2R_Guillaume::OnEnterBG"; - donpcevent "Guillaume_TV2B::OnBuild"; - donpcevent "Croix_TV2B::OnBuild"; - bg_monster $@TierraBG2_id1,"bat_a02",176,345,"Food Depot",1909,"Tierra_BG2::OnGuillaumeBreak"; - bg_monster $@TierraBG2_id2,"bat_a02",167,50,"Food Storage",1910,"Tierra_BG2::OnCroixBreak"; - bg_monster 0,"bat_a02",273,204,"Neutrality Flag",1911,"Tierra_BG2::OnNeutralBreak"; - - set .Neutral_Base, 0; - set $@TierraBG2_Victory, 0; - - set .Guardian_1, 0; - set .Guardian_2, 0; - set .Guardian_3, 0; - - enablenpc "Therapist in battle#tv21"; - enablenpc "Therapist in battle#tv22"; - disablenpc "Croix Vintenar#tv2"; - disablenpc "Guillaume Vintenar#tv2"; - // Respawner - donpcevent "#gtv2_respawn::OnBGStart"; - donpcevent "#ctv2_respawn::OnBGStart"; - donpcevent "#ntv2_respawn::OnBGStart"; - // Warp Teams - announce "Battleground -- Tierra Valley [80-99] has started!",0,0xF4A460; - bg_warp $@TierraBG2_id1,"bat_a02",353,344; - bg_warp $@TierraBG2_id2,"bat_a02",353,52; - // Final Messages - sleep 6000; - mapannounce "bat_a02","Guillaume Vintenar Axl Rose : Let's attack to burn down Croix's food storage",1,0x0000FF; - sleep 2000; - mapannounce "bat_a02","Croix Vintenar Swandery : Master of Valhalla! Let us be gifted with unfailing faith and courage",1,0xFF0000; - - initnpctimer; - end; - -OnNeutralBreak: - if( getcharid(4) == $@TierraBG2_id1 ) - { - mapannounce "bat_a02","Guillaume obtained a neurality banner, so they have an advantage.",1,0x0000FF; - bg_team_setxy $@TierraBG2_id2,42,16; - areawarp "bat_a02",52,208,61,217,"bat_a02",42,16; - } - else if( getcharid(4) == $@TierraBG2_id2 ) - { - mapannounce "bat_a02","Croix obtained a neutrality banner, so they have an advantage.",1,0xFF0000; - bg_team_setxy $@TierraBG2_id1,50,374; - areawarp "bat_a02",52,208,61,217,"bat_a02",50,374; - } - else end; - - set .Neutral_Base, getcharid(4); - bg_team_setxy .Neutral_Base,56,212; - - if( .Guardian_1 == 0 ) - set .Guardian_1, bg_monster(.Neutral_Base,"bat_a02",280,233,"Guardian",1949,"Tierra_BG2::OnGuardian1"); - else - bg_monster_set_team .Guardian_1, .Neutral_Base; - - if( .Guardian_2 == 0 ) - set .Guardian_2, bg_monster(.Neutral_Base,"bat_a02",287,203,"Guardian",1950,"Tierra_BG2::OnGuardian2"); - else - bg_monster_set_team .Guardian_2, .Neutral_Base; - - if( .Guardian_3 == 0 ) - set .Guardian_3, bg_monster(.Neutral_Base,"bat_a02",268,204,"Guardian",1949,"Tierra_BG2::OnGuardian3"); - else - bg_monster_set_team .Guardian_3, .Neutral_Base; - - sleep 10000; - if( $@TierraBG2 != 1 ) end; - - if( .Neutral_Base == $@TierraBG2_id1 ) - bg_monster .Neutral_Base,"bat_a02",273,204,"Guillaume Flag",1912,"Tierra_BG2::OnNeutralBreak"; - else if( .Neutral_Base == $@TierraBG2_id2 ) - bg_monster .Neutral_Base,"bat_a02",273,204,"Croix Flag",1913,"Tierra_BG2::OnNeutralBreak"; - end; - -OnGuardian1: set .Guardian_1, 0; end; -OnGuardian2: set .Guardian_2, 0; end; -OnGuardian3: set .Guardian_3, 0; end; - -OnGuillaumeBreak: - set $@TierraBG2_Victory, 2; - mapannounce "bat_a02","Croix Vintenar Swandery: We destroyed Guillaume's food storehouse. We won that! Wow!",1,0xFF0000; - donpcevent "Tierra_BG2::OnStop"; - end; - -OnCroixBreak: - set $@TierraBG2_Victory, 1; - mapannounce "bat_a02","Guillaume Vintenar Axl Rose: We destroyed Croix's food storehouse. We won that! Wow!",1,0x0000FF; - donpcevent "Tierra_BG2::OnStop"; - end; - -OnTimer2400000: - mapannounce "bat_a02","Battle of Tierra Gorge will ends in 5 minutes",1,0xF4A460; - end; -OnTimer2640000: - mapannounce "bat_a02","Battle of Tierra Gorge will ends in 1 minute",1,0xF4A460; - end; - -OnTimer2700000: - set $@TierraBG2_Victory, 3; // Draw Game - mapannounce "bat_a02","Battle of Tierra Gorge is over. The time is out, this is a Tie",1,0xF4A460; - donpcevent "Tierra_BG2::OnStop"; - end; - -OnStop: - set $@TierraBG2, 2; - disablenpc "Therapist in battle#tv21"; - disablenpc "Therapist in battle#tv22"; - donpcevent "#gtv2_respawn::OnBGStop"; - donpcevent "#ctv2_respawn::OnBGStop"; - donpcevent "#ntv2_respawn::OnBGStop"; - enablenpc "Croix Vintenar#tv2"; - enablenpc "Guillaume Vintenar#tv2"; - killmonster "bat_a02","Tierra_BG2::OnGuillaumeBreak"; - killmonster "bat_a02","Tierra_BG2::OnCroixBreak"; - killmonster "bat_a02","Tierra_BG2::OnNeutralBreak"; - killmonster "bat_a02","Tierra_BG2::OnGuardian1"; - killmonster "bat_a02","Tierra_BG2::OnGuardian2"; - killmonster "bat_a02","Tierra_BG2::OnGuardian3"; - stopnpctimer; - sleep 3000; - bg_warp $@TierraBG2_id1,"bat_a02",50,374; - bg_warp $@TierraBG2_id2,"bat_a02",42,16; - sleep 3000; - mapannounce "bat_a02","Battle of Tierra Gorge will close in 1 minute!",1,0xF4A460; - initnpctimer; - end; - -OnTimer30000: - if( $@TierraBG2 == 2 ) - mapannounce "bat_a02","Battle of Tierra Valley will close in 30 seconds!",1,0xF4A460; - end; -OnTimer50000: - if( $@TierraBG2 == 2 ) - mapannounce "bat_a02","Battle of Tierra Valley will close in 10 seconds!",1,0xF4A460; - end; - -OnTimer60000: - if( $@TierraBG2 != 2 ) - end; -OnReset: - stopnpctimer; - set .Neutral_Base, 0; - disablenpc "Croix Vintenar#tv2"; - disablenpc "Guillaume Vintenar#tv2"; - disablenpc "Therapist in battle#tv21"; - disablenpc "Therapist in battle#tv22"; - donpcevent "#gtv2_respawn::OnBGStop"; - donpcevent "#gtv2_respawn::OnBGStop"; - donpcevent "#ctv2_respawn::OnBGStop"; - - killmonster "bat_a02","Tierra_BG2::OnGuillaumeBreak"; - killmonster "bat_a02","Tierra_BG2::OnCroixBreak"; - killmonster "bat_a02","Tierra_BG2::OnNeutralBreak"; - killmonster "bat_a02","Tierra_BG2::OnGuardian1"; - killmonster "bat_a02","Tierra_BG2::OnGuardian2"; - killmonster "bat_a02","Tierra_BG2::OnGuardian3"; - donpcevent "Guillaume_TV2B::OnDestroy"; - donpcevent "Croix_TV2B::OnDestroy"; - - set $@TierraBG2_Victory, 0; - if( $@TierraBG2_id1 ) { bg_destroy $@TierraBG2_id1; set $@TierraBG2_id1, 0; } - if( $@TierraBG2_id2 ) { bg_destroy $@TierraBG2_id2; set $@TierraBG2_id2, 0; } - sleep 1000; - mapwarp "bat_a02","bat_room",155,150; - sleep 2000; - maprespawnguildid "bat_a02",0,3; // Just in case someone else - sleep 2000; - set $@TierraBG2, 0; - donpcevent "Tierra_BG2::OnReadyCheck"; // Maybe a game is ready to start - end; -} - -// Other Flags -// ********************************************************************* - -bat_a02,148,85,1 duplicate(Croix camp#bat) Croix camp#bat22 974 -bat_a02,155,85,1 duplicate(Croix camp#bat) Croix camp#bat23 974 -bat_a02,357,75,1 duplicate(Croix camp#bat) Croix camp#bat24 974 -bat_a02,348,74,1 duplicate(Croix camp#bat) Croix camp#bat25 974 -bat_a02,199,49,1 duplicate(Croix camp#bat) Croix camp#bat26 974 -bat_a02,168,16,1 duplicate(Croix camp#bat) Croix camp#bat27 974 -bat_a02,138,12,1 duplicate(Croix camp#bat) Croix camp#bat28 974 -bat_a02,108,35,1 duplicate(Croix camp#bat) Croix camp#bat29 974 -bat_a02,164,308,1 duplicate(Guillaume camp#bat) Guillaume camp#bat23 973 -bat_a02,157,308,1 duplicate(Guillaume camp#bat) Guillaume camp#bat24 973 -bat_a02,359,327,1 duplicate(Guillaume camp#bat) Guillaume camp#bat25 973 -bat_a02,350,326,1 duplicate(Guillaume camp#bat) Guillaume camp#bat26 973 -bat_a02,209,344,1 duplicate(Guillaume camp#bat) Guillaume camp#bat27 973 -bat_a02,173,380,1 duplicate(Guillaume camp#bat) Guillaume camp#bat28 973 -bat_a02,150,380,1 duplicate(Guillaume camp#bat) Guillaume camp#bat29 973 -bat_a02,118,357,1 duplicate(Guillaume camp#bat) Guillaume camp#bat30 973 -bat_a02,119,336,1 duplicate(Guillaume camp#bat) Guillaume camp#bat31 973 - -// Barricades -// ********************************************************************* - -- script Guillaume_TV2B -1,{ - end; - -OnBuild: - for( set .@i, 0; .@i < 16; set .@i, .@i + 1 ) - bg_monster 0,"bat_a02",170+.@i,130,"Barricade",1906,"Guillaume_TV2B::OnWall"; - - setwall "bat_a02",170,130,16,6,1,"bat_a02_g1"; - set .MyMobCount,16; - end; - -OnDestroy: - killmonster "bat_a02","Guillaume_TV2B::OnWall"; - if (checkwall("bat_a02_g1") == true) - delwall "bat_a02_g1"; - set .MyMobCount,0; - end; - -OnWall: - if( set(.MyMobCount,.MyMobCount - 1) < 1 ) - { - delwall "bat_a02_g1"; - mapannounce "bat_a02","South Gate : The Gate has been Destroy!!",1,0xF4A460; - } - end; -} - -- script Croix_TV2B -1,{ - end; - -OnBuild: - for( set .@i, 0; .@i < 16; set .@i, .@i + 1 ) - bg_monster 0,"bat_a02",186+.@i,266,"Barricade",1906,"Croix_TV2B::OnWall"; - - setwall "bat_a02",186,266,16,6,1,"bat_a02_c1"; - set .MyMobCount,16; - end; - -OnDestroy: - killmonster "bat_a02","Croix_TV2B::OnWall"; - delwall "bat_a02_c1"; - set .MyMobCount,0; - end; - -OnWall: - if( set(.MyMobCount,.MyMobCount - 1) < 1 ) - { - delwall "bat_a02_c1"; - mapannounce "bat_a02","North Gate : A Gate has been Destroy!!",1,0xF4A460; - } - end; -} - -// Battleground rewards -// ********************************************************************* - -bat_a02,45,19,3 script Croix Vintenar#tv2 415,{ - if( $@TierraBG2_Victory ) - { - if( $@TierraBG2_Victory == Bat_Team ) - { // Victory - set .@Reward, 3; - mes "[Swandery]"; - mes "Blessed Croax!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - } - else - { // - set .@Reward, 1; - mes "[Swandery]"; - mes "Oh, " + strcharinfo(0) + ". Don't be sad."; - mes "Even though we didn't win, we did our best."; - mes "This is a Royal gift from Croix, and please don't forget this battle. We can win the next."; - close2; - } - - setquest 2069; - getitem 7828, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} - -bat_a02,53,377,3 script Guillaume Vintenar#tv2 419,{ - if( $@TierraBG2_Victory ) - { - if( $@TierraBG2_Victory == Bat_Team ) - { // Victory - set .@Reward, 3; - mes "[Swandery]"; - mes "Blessed Guillaume!!"; - mes "Let's enjoy our glorious victory!"; - mes "" + strcharinfo(0) + ", its a sign reflecting victory"; - close2; - } - else - { // - set .@Reward, 1; - mes "[Swandery]"; - mes "You lost, but you're dedicated to this battle."; - mes "This is a reward for your great dedication by Guillaume Marollo!"; - mes "Just take this defeat a lesson, and later you would definitely learn."; - close2; - } - - setquest 2069; - getitem 7828, .@Reward; - bg_leave; - warp "bat_room",155,150; - end; - } - end; -} - -// Battleground Therapist -// ********************************************************************* - -bat_a02,60,216,3 script Ghost#tv23 950,{ - mes "[Ghost in valley]"; - mes "Boo...Boo..."; - specialeffect2 EF_HEAL; - close; -} - -bat_a02,53,377,3 script Therapist in battle#tv22 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -bat_a02,45,18,3 script Therapist in battle#tv21 95,{ - mes "[Therapist in battle]"; - mes "Just close your eyes, and take a deep breathe."; - mes "You can be free from pain."; - specialeffect2 EF_HEAL; - close; -} - -// Battleground Respawn -// ********************************************************************* - -bat_a02,57,213,0 script #ntv2_respawn 139,{ - end; - -OnBGStart: - initnpctimer; - end; - -OnBGStop: - stopnpctimer; - end; - -OnTimer19000: - misceffect EF_SANCTUARY; - end; - -OnTimer20000: - areapercentheal "bat_a02",52,208,61,217,100,100; - areawarp "bat_a02",52,208,61,217,"bat_a02",301,208; - initnpctimer; - end; -} - -bat_a02,50,374,0 script #gtv2_respawn 139,{ - end; - -OnBGStart: - initnpctimer; - end; - -OnBGStop: - stopnpctimer; - end; - -OnTimer24000: - misceffect EF_SANCTUARY; - end; - -OnTimer25000: - areapercentheal "bat_a02",46,370,54,378,100,100; - areawarp "bat_a02",46,370,54,378,"bat_a02",354,340; - initnpctimer; - end; -} - -bat_a02,42,16,0 script #ctv2_respawn 139,{ - end; - -OnBGStart: - initnpctimer; - end; - -OnBGStop: - stopnpctimer; - end; - -OnTimer24000: - misceffect EF_SANCTUARY; - end; - -OnTimer25000: - areapercentheal "bat_a02",38,12,47,21,100,100; - areawarp "bat_a02",38,12,47,21,"bat_a02",354,57; - initnpctimer; - end; -} diff --git a/src/common/utilities.hpp b/src/common/utilities.hpp index c64e7e6c12..e00228a378 100644 --- a/src/common/utilities.hpp +++ b/src/common/utilities.hpp @@ -162,6 +162,19 @@ namespace rathena { return false; } + /** + * Erase an index value from a vector + * @param vector: Vector to erase value from + * @param index: Index value to remove + */ + template void erase_at(std::vector& vector, size_t index) { + if (vector.size() == 1) { + vector.clear(); + vector.shrink_to_fit(); + } else + vector.erase(vector.begin() + index); + } + bool safe_addition( int64 a, int64 b, int64& result ); bool safe_substraction( int64 a, int64 b, int64& result ); bool safe_multiplication( int64 a, int64 b, int64& result ); diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 60d172f42c..f08e876446 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -1620,6 +1620,34 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam return damage; } +/** + * Determines whether battleground target can be hit + * @param src: Source of attack + * @param bl: Target of attack + * @param skill_id: Skill ID used + * @param flag: Special flags + * @return Can be hit (true) or can't be hit (false) + */ +bool battle_can_hit_bg_target(struct block_list *src, struct block_list *bl, uint16 skill_id, int flag) +{ + struct mob_data* md = BL_CAST(BL_MOB, bl); + struct unit_data *ud = unit_bl2ud(bl); + + if (ud && ud->immune_attack) + return false; + if (md && md->bg_id) { + if (status_bl_has_mode(bl, MD_SKILL_IMMUNE) && flag&BF_SKILL) //Skill immunity. + return false; + if (src->type == BL_PC) { + struct map_session_data *sd = map_id2sd(src->id); + + if (sd && sd->bg_id == md->bg_id) + return false; + } + } + return true; +} + /** * Calculates BG related damage adjustments. * @param src @@ -1638,6 +1666,9 @@ int64 battle_calc_bg_damage(struct block_list *src, struct block_list *bl, int64 if( !damage ) return 0; + if (!battle_can_hit_bg_target(src, bl, skill_id, flag)) + return 0; + if(skill_get_inf2(skill_id, INF2_IGNOREBGREDUCTION)) return damage; //skill that ignore bg map reduction @@ -8591,6 +8622,7 @@ static const struct _battle_data { { "boss_nopc_move_rate", &battle_config.boss_nopc_move_rate, 100, 0, 100, }, { "hom_idle_no_share", &battle_config.hom_idle_no_share, 0, 0, INT_MAX, }, { "devotion_standup_fix", &battle_config.devotion_standup_fix, 1, 0, 1, }, + { "feature.bgqueue", &battle_config.feature_bgqueue, 1, 0, 1, }, #include "../custom/battle_config_init.inc" }; @@ -8679,6 +8711,13 @@ void battle_adjust_conf() } #endif +#if PACKETVER < 20120101 + if (battle_config.feature_bgqueue) { + ShowWarning("conf/battle/feature.conf:bgqueue is enabled but it requires PACKETVER 2012-01-01 or newer, disabling...\n"); + battle_config.feature_bgqueue = 0; + } +#endif + #if PACKETVER > 20120000 && PACKETVER < 20130515 /* Exact date (when it started) not known */ if (battle_config.feature_auction) { ShowWarning("conf/battle/feature.conf:feature.auction is enabled but it is not stable on PACKETVER " EXPAND_AND_QUOTE(PACKETVER) ", disabling...\n"); diff --git a/src/map/battle.hpp b/src/map/battle.hpp index 27c8b81d4a..c26efe3ff3 100644 --- a/src/map/battle.hpp +++ b/src/map/battle.hpp @@ -671,6 +671,7 @@ struct Battle_Config int boss_nopc_move_rate; int hom_idle_no_share; int devotion_standup_fix; + int feature_bgqueue; #include "../custom/battle_config_struct.inc" }; diff --git a/src/map/battleground.cpp b/src/map/battleground.cpp index 990c8dde88..760afa2e82 100644 --- a/src/map/battleground.cpp +++ b/src/map/battleground.cpp @@ -3,194 +3,527 @@ #include "battleground.hpp" +#include +#include + #include "../common/cbasetypes.hpp" #include "../common/malloc.hpp" #include "../common/nullpo.hpp" +#include "../common/random.hpp" #include "../common/showmsg.hpp" #include "../common/strlib.hpp" #include "../common/timer.hpp" +#include "../common/utilities.hpp" #include "battle.hpp" #include "clif.hpp" #include "guild.hpp" #include "homunculus.hpp" +#include "mapreg.hpp" #include "mercenary.hpp" #include "mob.hpp" #include "npc.hpp" +#include "party.hpp" #include "pc.hpp" #include "pet.hpp" -static DBMap* bg_team_db; // int bg_id -> struct battleground_data* -static unsigned int bg_team_counter = 0; // Next bg_id +using namespace rathena; -struct battleground_data* bg_team_search(int bg_id) -{ // Search a BG Team using bg_id - if( !bg_id ) - return NULL; +BattlegroundDatabase battleground_db; +std::unordered_map> bg_team_db; +std::vector> bg_queues; - return (struct battleground_data *)idb_get(bg_team_db, bg_id); +const std::string BattlegroundDatabase::getDefaultLocation() { + return std::string(db_path) + "/battleground_db.yml"; } -struct map_session_data* bg_getavailablesd(struct battleground_data *bg) -{ - int i; +/** + * Reads and parses an entry from the battleground_db + * @param node: The YAML node containing the entry + * @return count of successfully parsed rows + */ +uint64 BattlegroundDatabase::parseBodyNode(const YAML::Node &node) { + uint32 id; - nullpo_retr(NULL, bg); - - ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd != NULL); - - return ( i < MAX_BG_MEMBERS ) ? bg->members[i].sd : NULL; -} - -int bg_team_delete(int bg_id) -{ // Deletes BG Team from db - int i; - struct battleground_data *bg = bg_team_search(bg_id); - - if( bg == NULL ) + if (!this->asUInt32(node, "Id", id)) return 0; - for( i = 0; i < MAX_BG_MEMBERS; i++ ) { - struct map_session_data *sd; + std::shared_ptr bg = this->find(id); + bool exists = bg != nullptr; - if( (sd = bg->members[i].sd) == NULL ) - continue; + if (!exists) { + if (!this->nodesExist(node, { "Name", "Locations" })) + return 0; - bg_send_dot_remove(sd); - sd->bg_id = 0; + bg = std::make_shared(); + bg->id = id; } - idb_remove(bg_team_db, bg_id); + if (this->nodeExists(node, "Name")) { + std::string name; + + if (!this->asString(node, "Name", name)) + return 0; + + name.resize(NAME_LENGTH); + bg->name = name; + } + + if (this->nodeExists(node, "MinPlayers")) { + int min; + + if (!this->asInt32(node, "MinPlayers", min)) + return 0; + + if (min * 2 > MAX_BG_MEMBERS) { + this->invalidWarning(node["MinPlayers"], "Minimum players %d exceeds MAX_BG_MEMBERS, capping to %d.\n", min, MAX_BG_MEMBERS / 2); + min = MAX_BG_MEMBERS / 2; + } + + bg->required_players = min; + } else { + if (!exists) + bg->required_players = 1; + } + + if (this->nodeExists(node, "MaxPlayers")) { + int max; + + if (!this->asInt32(node, "MaxPlayers", max)) + return 0; + + if (max * 2 > MAX_BG_MEMBERS) { + this->invalidWarning(node["MaxPlayers"], "Maximum players %d exceeds MAX_BG_MEMBERS, capping to %d.\n", max, MAX_BG_MEMBERS / 2); + max = MAX_BG_MEMBERS / 2; + } + + bg->max_players = max; + } else { + if (!exists) + bg->max_players = MAX_BG_MEMBERS / 2; + } + + if (this->nodeExists(node, "MinLevel")) { + int min; + + if (!this->asInt32(node, "MinLevel", min)) + return 0; + + if (min > MAX_LEVEL) { + this->invalidWarning(node["MinLevel"], "Minimum level %d exceeds MAX_LEVEL, capping to %d.\n", min, MAX_LEVEL); + min = MAX_LEVEL; + } + + bg->min_lvl = min; + } else { + if (!exists) + bg->min_lvl = 1; + } + + if (this->nodeExists(node, "MaxLevel")) { + int max; + + if (!this->asInt32(node, "MaxLevel", max)) + return 0; + + if (max > MAX_LEVEL) { + this->invalidWarning(node["MaxLevel"], "Maximum level %d exceeds MAX_LEVEL, capping to %d.\n", max, MAX_LEVEL); + max = MAX_LEVEL; + } + + bg->max_lvl = max; + } else { + if (!exists) + bg->max_lvl = MAX_LEVEL; + } + + if (this->nodeExists(node, "Deserter")) { + uint32 deserter; + + if (!this->asUInt32(node, "Deserter", deserter)) + return 0; + + bg->deserter_time = deserter; + } else { + if (!exists) + bg->deserter_time = 600; + } + + if (this->nodeExists(node, "StartDelay")) { + uint32 delay; + + if (!this->asUInt32(node, "StartDelay", delay)) + return 0; + + bg->start_delay = delay; + } else { + if (!exists) + bg->start_delay = 30; + } + + if (this->nodeExists(node, "Locations")) { + int count = 0; + + for (const auto &locationit : node["Locations"]) { + const YAML::Node &location = locationit; + s_battleground_map map_entry; + + if (this->nodeExists(location, "Map")) { + std::string map_name; + + if (!this->asString(location, "Map", map_name)) + return 0; + + map_entry.mapid = map_mapname2mapid(map_name.c_str()); + + if (map_entry.mapid == -1) { + this->invalidWarning(location["Map"], "Invalid battleground map name %s, skipping.\n", map_name.c_str()); + return 0; + } + } + + if (this->nodeExists(location, "StartEvent")) { + if (!this->asString(location, "StartEvent", map_entry.bgcallscript)) + return 0; + + map_entry.bgcallscript.resize(EVENT_NAME_LENGTH); + + if (map_entry.bgcallscript.find("::On") == std::string::npos) { + this->invalidWarning(location["StartEvent"], "Battleground StartEvent label %s should begin with '::On', skipping.\n", map_entry.bgcallscript.c_str()); + return 0; + } + } + + std::vector team_list = { "TeamA", "TeamB" }; + + for (const auto &it : team_list) { + const YAML::Node &team = location; + + if (this->nodeExists(team, it)) { + s_battleground_team *team_ptr; + + if (it.find("TeamA") != std::string::npos) + team_ptr = &map_entry.team1; + else if (it.find("TeamB") != std::string::npos) + team_ptr = &map_entry.team2; + else { + this->invalidWarning(team[it], "An invalid Team is defined.\n"); + return 0; + } + + if (this->nodeExists(team[it], "RespawnX")) { + if (!this->asInt16(team[it], "RespawnX", team_ptr->warp_x)) + return 0; + } + + if (this->nodeExists(team[it], "RespawnY")) { + if (!this->asInt16(team[it], "RespawnY", team_ptr->warp_y)) + return 0; + } + + if (this->nodeExists(team[it], "DeathEvent")) { + if (!this->asString(team[it], "DeathEvent", team_ptr->death_event)) + return 0; + + team_ptr->death_event.resize(EVENT_NAME_LENGTH); + + if (team_ptr->death_event.find("::On") == std::string::npos) { + this->invalidWarning(team["DeathEvent"], "Battleground DeathEvent label %s should begin with '::On', skipping.\n", team_ptr->death_event.c_str()); + return 0; + } + } + + if (this->nodeExists(team[it], "QuitEvent")) { + if (!this->asString(team[it], "QuitEvent", team_ptr->quit_event)) + return 0; + + team_ptr->quit_event.resize(EVENT_NAME_LENGTH); + + if (team_ptr->quit_event.find("::On") == std::string::npos) { + this->invalidWarning(team["QuitEvent"], "Battleground QuitEvent label %s should begin with '::On', skipping.\n", team_ptr->quit_event.c_str()); + return 0; + } + } + + if (this->nodeExists(team[it], "Variable")) { + if (!this->asString(team[it], "Variable", team_ptr->bg_id_var)) + return 0; + + team_ptr->bg_id_var.resize(NAME_LENGTH); + } + + map_entry.id = count++; + map_entry.isReserved = false; + } + } + + bg->maps.push_back(map_entry); + } + } + + if (!exists) + this->put(id, bg); return 1; } -int bg_team_warp(int bg_id, unsigned short mapindex, short x, short y) -{ // Warps a Team - int i; - struct battleground_data *bg = bg_team_search(bg_id); - - if( bg == NULL ) - return 0; - - for( i = 0; i < MAX_BG_MEMBERS; i++ ) - if( bg->members[i].sd != NULL ) pc_setpos(bg->members[i].sd, mapindex, x, y, CLR_TELEPORT); - return 1; -} - -int bg_send_dot_remove(struct map_session_data *sd) +/** + * Search for a battleground based on the given name + * @param name: Battleground name + * @return s_battleground_type on success or nullptr on failure + */ +std::shared_ptr bg_search_name(const char *name) { + for (const auto &entry : battleground_db) { + auto bg = entry.second; + + if (!stricmp(bg->name.c_str(), name)) + return bg; + } + + return nullptr; +} + +/** + * Search for an available player in Battleground + * @param bg: Battleground data + * @return map_session_data + */ +struct map_session_data* bg_getavailablesd(s_battleground_data *bg) +{ + nullpo_retr(nullptr, bg); + + return (bg->members.size() != 0) ? bg->members[0].sd : nullptr; +} + +/** + * Delete a Battleground team from the db + * @param bg_id: Battleground ID + * @return True on success or false otherwise + */ +bool bg_team_delete(int bg_id) +{ + std::shared_ptr bgteam = util::umap_find(bg_team_db, bg_id); + + if (bgteam) { + for (const auto &pl_sd : bgteam->members) { + bg_send_dot_remove(pl_sd.sd); + pl_sd.sd->bg_id = 0; + } + + bg_team_db.erase(bg_id); + + return true; + } + + return false; +} + +/** + * Warps a Battleground team + * @param bg_id: Battleground ID + * @param mapindex: Map Index + * @param x: X coordinate + * @param y: Y coordinate + * @return True on success or false otherwise + */ +bool bg_team_warp(int bg_id, unsigned short mapindex, short x, short y) +{ + std::shared_ptr bgteam = util::umap_find(bg_team_db, bg_id); + + if (bgteam) { + for (const auto &pl_sd : bgteam->members) + pc_setpos(pl_sd.sd, mapindex, x, y, CLR_TELEPORT); + + return true; + } + + return false; +} + +/** + * Remove a player's Battleground map marker + * @param sd: Player data + */ +void bg_send_dot_remove(struct map_session_data *sd) +{ + nullpo_retv(sd); + if( sd && sd->bg_id ) clif_bg_xy_remove(sd); - return 0; + return; } -int bg_team_join(int bg_id, struct map_session_data *sd) -{ // Player joins team - int i; - struct battleground_data *bg = bg_team_search(bg_id); +/** + * Join a player to a Battleground team + * @param bg_id: Battleground ID + * @param sd: Player data + * @param is_queue: Joined from queue + * @return True on success or false otherwise + */ +bool bg_team_join(int bg_id, struct map_session_data *sd, bool is_queue) +{ + if (!sd || sd->bg_id) + return false; - if( bg == NULL || sd == NULL || sd->bg_id ) - return 0; + std::shared_ptr bgteam = util::umap_find(bg_team_db, bg_id); - ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == NULL); - if( i == MAX_BG_MEMBERS ) - return 0; // No free slots + if (bgteam) { + if (bgteam->members.size() == MAX_BG_MEMBERS) + return false; // No free slots - sd->bg_id = bg_id; - bg->members[i].sd = sd; - bg->members[i].x = sd->bl.x; - bg->members[i].y = sd->bl.y; - bg->count++; + s_battleground_member_data member = {}; - guild_send_dot_remove(sd); + sd->bg_id = bg_id; + member.sd = sd; + member.x = sd->bl.x; + member.y = sd->bl.y; + if (is_queue) { // Save the location from where the person entered the battleground + member.entry_point.map = sd->mapindex; + member.entry_point.x = sd->bl.x; + member.entry_point.y = sd->bl.y; + } + bgteam->members.push_back(member); - for( i = 0; i < MAX_BG_MEMBERS; i++ ) { - struct map_session_data *pl_sd; + guild_send_dot_remove(sd); - if( (pl_sd = bg->members[i].sd) != NULL && pl_sd != sd ) - clif_hpmeter_single(sd->fd, pl_sd->bl.id, pl_sd->battle_status.hp, pl_sd->battle_status.max_hp); + for (const auto &pl_sd : bgteam->members) { + if (pl_sd.sd != sd) + clif_hpmeter_single(sd->fd, pl_sd.sd->bl.id, pl_sd.sd->battle_status.hp, pl_sd.sd->battle_status.max_hp); + } + + clif_bg_hp(sd); + clif_bg_xy(sd); + return true; } - clif_bg_hp(sd); - clif_bg_xy(sd); - return 1; + return false; } -int bg_team_leave(struct map_session_data *sd, int flag) -{ // Single Player leaves team - int i, bg_id; - struct battleground_data *bg; - char output[128]; - - if( sd == NULL || !sd->bg_id ) - return 0; +/** + * Remove a player from Battleground team + * @param sd: Player data + * @param quit: True if closed client or false otherwise + * @param deserter: Whether to apply the deserter status or not + * @return Remaining count in Battleground team or -1 on failure + */ +int bg_team_leave(struct map_session_data *sd, bool quit, bool deserter) +{ + if (!sd || !sd->bg_id) + return -1; bg_send_dot_remove(sd); - bg_id = sd->bg_id; + + int bg_id = sd->bg_id; + std::shared_ptr bgteam = util::umap_find(bg_team_db, bg_id); + sd->bg_id = 0; - if( (bg = bg_team_search(bg_id)) == NULL ) - return 0; + if (bgteam) { + char output[CHAT_SIZE_MAX]; + int i; - ARR_FIND(0, MAX_BG_MEMBERS, i, bg->members[i].sd == sd); - if( i < MAX_BG_MEMBERS ) // Removes member from BG - memset(&bg->members[i], 0, sizeof(bg->members[0])); + ARR_FIND(0, bgteam->members.size(), i, bgteam->members[i].sd == sd); + if (i < bgteam->members.size()) { // Removes member from BG + if (bgteam->members[i].entry_point.map != 0) { + int16 map_id = map_mapindex2mapid(bgteam->members[i].entry_point.map); - bg->count--; + if (!map_getmapflag(map_id, MF_NOSAVE)) + pc_setpos(sd, bgteam->members[i].entry_point.map, bgteam->members[i].entry_point.x, bgteam->members[i].entry_point.y, CLR_TELEPORT); + else + pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); // Warp to save point if the entry map has no save flag. + } + util::erase_at(bgteam->members, i); + } - if( flag ) - sprintf(output, "Server : %s has quit the game...", sd->status.name); - else - sprintf(output, "Server : %s is leaving the battlefield...", sd->status.name); + if (quit) + sprintf(output, "Server: %s has quit the game...", sd->status.name); + else + sprintf(output, "Server: %s is leaving the battlefield...", sd->status.name); - clif_bg_message(bg, 0, "Server", output, strlen(output) + 1); + clif_bg_message(bgteam.get(), 0, "Server", output, strlen(output) + 1); - if( bg->logout_event[0] && flag ) - npc_event(sd, bg->logout_event, 0); + if (!bgteam->logout_event.empty() && quit) + npc_event(sd, bgteam->logout_event.c_str(), 0); - return bg->count; + if (deserter) { + std::shared_ptr bg = battleground_db.find(bg_id); + + if (bg) + sc_start(nullptr, &sd->bl, SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT, 100, 1, static_cast(bg->deserter_time) * 1000); // Deserter timer + } + + return bgteam->members.size(); + } + + return -1; } -int bg_member_respawn(struct map_session_data *sd) -{ // Respawn after killed - struct battleground_data *bg; - - if( sd == NULL || !pc_isdead(sd) || !sd->bg_id || (bg = bg_team_search(sd->bg_id)) == NULL ) - return 0; - - if( bg->mapindex == 0 ) - return 0; // Respawn not handled by Core - - pc_setpos(sd, bg->mapindex, bg->x, bg->y, CLR_OUTSIGHT); - status_revive(&sd->bl, 1, 100); - - return 1; // Warped -} - -int bg_create(unsigned short mapindex, short rx, short ry, const char *ev, const char *dev) +/** + * Respawn a Battleground player + * @param sd: Player data + * @return True on success or false otherwise + */ +bool bg_member_respawn(struct map_session_data *sd) { - struct battleground_data *bg; - bg_team_counter++; + if (!sd || !sd->bg_id || !pc_isdead(sd)) + return false; - CREATE(bg, struct battleground_data, 1); - bg->bg_id = bg_team_counter; - bg->count = 0; - bg->mapindex = mapindex; - bg->x = rx; - bg->y = ry; - safestrncpy(bg->logout_event, ev, sizeof(bg->logout_event)); - safestrncpy(bg->die_event, dev, sizeof(bg->die_event)); + std::shared_ptr bgteam = util::umap_find(bg_team_db, sd->bg_id); - memset(&bg->members, 0, sizeof(bg->members)); - idb_put(bg_team_db, bg_team_counter, bg); + if (bgteam) { + if (bgteam->cemetery.map == 0) + return false; // Respawn not handled by Core - return bg->bg_id; + pc_setpos(sd, bgteam->cemetery.map, bgteam->cemetery.x, bgteam->cemetery.y, CLR_OUTSIGHT); + status_revive(&sd->bl, 1, 100); + + return true; // Warped + } + + return false; } +/** + * Initialize Battleground data + * @param mapindex: Map Index + * @param rx: Return X coordinate (on death) + * @param ry: Return Y coordinate (on death) + * @param ev: Logout NPC Event + * @param dev: Death NPC Event + * @return Battleground ID + */ +int bg_create(uint16 mapindex, s_battleground_team* team) +{ + int bg_team_counter = 1; + + while (bg_team_db.find(bg_team_counter) != bg_team_db.end()) + bg_team_counter++; + + bg_team_db[bg_team_counter] = std::make_shared(); + + std::shared_ptr bg = util::umap_find(bg_team_db, bg_team_counter); + + bg->id = bg_team_counter; + bg->cemetery.map = mapindex; + bg->cemetery.x = team->warp_x; + bg->cemetery.y = team->warp_y; + bg->logout_event = team->quit_event.c_str(); + bg->die_event = team->death_event.c_str(); + bg->members.clear(); + + return bg->id; +} + +/** + * Get an object's Battleground ID + * @param bl: Object + * @return Battleground ID + */ int bg_team_get_id(struct block_list *bl) { nullpo_ret(bl); + switch( bl->type ) { case BL_PC: return ((TBL_PC*)bl)->bg_id; @@ -202,7 +535,7 @@ int bg_team_get_id(struct block_list *bl) struct map_session_data *msd; struct mob_data *md = (TBL_MOB*)bl; - if( md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL ) + if( md->special_state.ai && !(msd = map_id2sd(md->master_id)) ) return msd->bg_id; return md->bg_id; @@ -222,38 +555,41 @@ int bg_team_get_id(struct block_list *bl) return 0; } -int bg_send_message(struct map_session_data *sd, const char *mes, int len) +/** + * Send a Battleground chat message + * @param sd: Player data + * @param mes: Message + * @param len: Message length + */ +void bg_send_message(struct map_session_data *sd, const char *mes, int len) { - struct battleground_data *bg; + nullpo_retv(sd); - nullpo_ret(sd); - - if( sd->bg_id == 0 || (bg = bg_team_search(sd->bg_id)) == NULL ) - return 0; + if (!sd->bg_id) + return; - clif_bg_message(bg, sd->bl.id, sd->status.name, mes, len); + std::shared_ptr bgteam = util::umap_find(bg_team_db, sd->bg_id); - return 0; + if (bgteam) + clif_bg_message(bgteam.get(), sd->bl.id, sd->status.name, mes, len); + + return; } /** + * Update a player's Battleground minimap icon * @see DBApply */ -int bg_send_xy_timer_sub(DBKey key, DBData *data, va_list ap) +int bg_send_xy_timer_sub(std::shared_ptr bg) { - struct battleground_data *bg = (struct battleground_data *)db_data2ptr(data); struct map_session_data *sd; - int i; - nullpo_ret(bg); + for (auto &pl_sd : bg->members) { + sd = pl_sd.sd; - for( i = 0; i < MAX_BG_MEMBERS; i++ ) { - if( (sd = bg->members[i].sd) == NULL ) - continue; - - if( sd->bl.x != bg->members[i].x || sd->bl.y != bg->members[i].y ) { // xy update - bg->members[i].x = sd->bl.x; - bg->members[i].y = sd->bl.y; + if (sd->bl.x != pl_sd.x || sd->bl.y != pl_sd.y) { // xy update + pl_sd.x = sd->bl.x; + pl_sd.y = sd->bl.y; clif_bg_xy(sd); } } @@ -261,20 +597,839 @@ int bg_send_xy_timer_sub(DBKey key, DBData *data, va_list ap) return 0; } -TIMER_FUNC(bg_send_xy_timer){ - bg_team_db->foreach(bg_team_db, bg_send_xy_timer_sub, tick); +/** + * Update a player's Battleground minimap icon + * @param tid: Timer ID + * @param tick: Timer + * @param id: ID + * @return 0 on success or 1 otherwise + */ +TIMER_FUNC(bg_send_xy_timer) +{ + for (const auto &entry : bg_team_db) + bg_send_xy_timer_sub(entry.second); return 0; } +/** + * Mark a Battleground as ready to begin queuing + * @param tid: Timer ID + * @param tick: Timer + * @param id: ID + * @return 0 on success or 1 otherwise + */ +static TIMER_FUNC(bg_on_ready_loopback) +{ + s_battleground_queue *queue = (s_battleground_queue*)data; + + nullpo_retr(1, queue); + + std::shared_ptr bg = battleground_db.find(queue->id); + + if (bg) { + bg_queue_on_ready(bg->name.c_str(), std::shared_ptr(queue)); + return 0; + } else { + ShowError("bg_on_ready_loopback: Can't find battleground %d in the battlegrounds database.\n", queue->id); + return 1; + } +} + +/** + * Reset Battleground queue data + * @param tid: Timer ID + * @param tick: Timer + * @param id: ID + * @return 0 on success or 1 otherwise + */ +static TIMER_FUNC(bg_on_ready_expire) +{ + s_battleground_queue *queue = (s_battleground_queue*)data; + + nullpo_retr(1, queue); + + queue->in_ready_state = false; + queue->map->isReserved = false; // Remove reservation to free up for future queue + queue->map = nullptr; + queue->accepted_players = 0; // Reset the queue count + + std::string bg_name = battleground_db.find(queue->id)->name; + + for (const auto &sd : queue->teama_members) { + sd->bg_queue_accept_state = false; + clif_bg_queue_apply_result(BG_APPLY_QUEUE_FINISHED, bg_name.c_str(), sd); + } + + for (const auto &sd : queue->teamb_members) { + sd->bg_queue_accept_state = false; + clif_bg_queue_apply_result(BG_APPLY_QUEUE_FINISHED, bg_name.c_str(), sd); + } + return 0; +} + +/** + * Start a Battleground + * @param tid: Timer ID + * @param tick: Timer + * @param id: ID + * @return 0 on success or 1 otherwise + */ +static TIMER_FUNC(bg_on_ready_start) +{ + s_battleground_queue *queue = (s_battleground_queue*)data; + + nullpo_retr(1, queue); + + bg_queue_start_battleground(std::shared_ptr(queue)); + return 0; +} + +/** + * Check if the given player is in a battleground + * @param sd: Player data + * @return True if in a battleground or false otherwise + */ +bool bg_player_is_in_bg_map(struct map_session_data *sd) +{ + nullpo_retr(false, sd); + + for (const auto &pair : battleground_db) { + for (const auto &it : pair.second->maps) { + if (it.mapid == sd->bl.m) + return true; + } + } + + return false; +} + +/** + * Battleground status change check + * @param sd: Player data + * @param name: Battleground name + * @return True if the player is good to join a queue or false otherwise + */ +static bool bg_queue_check_status(struct map_session_data* sd, const char *name) +{ + nullpo_retr(false, sd); + + if (sd->sc.count) { + if (sd->sc.data[SC_ENTRY_QUEUE_APPLY_DELAY]) { // Exclude any player who's recently left a battleground queue + char buf[CHAT_SIZE_MAX]; + + sprintf(buf, msg_txt(sd, 339), (get_timer(sd->sc.data[SC_ENTRY_QUEUE_APPLY_DELAY]->timer)->tick - gettick()) / 1000); // You can't apply to a battleground queue for %d seconds due to recently leaving one. + clif_bg_queue_apply_result(BG_APPLY_NONE, name, sd); + clif_messagecolor(&sd->bl, color_table[COLOR_LIGHT_GREEN], buf, false, SELF); + return false; + } + + if (sd->sc.data[SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT]) { // Exclude any player who's recently deserted a battleground + char buf[CHAT_SIZE_MAX]; + t_tick status_tick = get_timer(sd->sc.data[SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT]->timer)->tick, tick = gettick(); + + sprintf(buf, msg_txt(sd, 338), ((status_tick - tick) / 1000) / 60, ((status_tick - tick) / 1000) % 60); // You can't apply to a battleground queue due to recently deserting a battleground. Time remaining: %d minutes and %d seconds. + clif_bg_queue_apply_result(BG_APPLY_NONE, name, sd); + clif_messagecolor(&sd->bl, color_table[COLOR_LIGHT_GREEN], buf, false, SELF); + return false; + } + } + + return true; +} + +/** + * Check to see if a Battleground is joinable + * @param bg: Battleground data + * @param sd: Player data + * @param name: Battleground name + * @return True on success or false otherwise + */ +bool bg_queue_check_joinable(std::shared_ptr bg, struct map_session_data *sd, const char *name) +{ + nullpo_retr(false, sd); + + if (bg->min_lvl && sd->status.base_level < bg->min_lvl) { // Check min level if min_lvl isn't 0 + clif_bg_queue_apply_result(BG_APPLY_PLAYER_LEVEL, name, sd); + return false; + } + + if (bg->max_lvl && sd->status.base_level > bg->max_lvl) { // Check max level if max_lvl isn't 0 + clif_bg_queue_apply_result(BG_APPLY_PLAYER_LEVEL, name, sd); + return false; + } + + if (!bg_queue_check_status(sd, name)) + return false; + + if (bg_player_is_in_bg_map(sd)) { // Is the player currently in a battleground map? Reject them. + clif_bg_queue_apply_result(BG_APPLY_NONE, name, sd); + clif_messagecolor(&sd->bl, color_table[COLOR_LIGHT_GREEN], msg_txt(sd, 337), false, SELF); // You may not join a battleground queue when you're in a battleground map. + return false; + } + + return true; // Return true if all conditions are met. +} + +/** + * Sub function for reserving a slot in the Battleground if it's joinable + * @param name: Battleground map name + * @param state: Whether to mark reserved or not + * @return True on success or false otherwise + */ +bool bg_queue_reservation(const char *name, bool state) +{ + int16 mapid = map_mapname2mapid(name); + + for (const auto &pair : battleground_db) { + // Bound checking isn't needed since we iterate within battleground_db's bound. + for (auto &it : pair.second->maps) { + if (it.mapid == mapid) { + it.isReserved = state; + return true; + } + } + } + + return false; +} + +/** + * Initialize a Battleground queue + * @param bg_id: Battleground ID + * @param req_players: Required amount of players + * @return s_battleground_queue* + */ +std::shared_ptr bg_queue_create(int bg_id, int req_players) +{ + auto queue = std::make_shared(); + + queue->id = bg_id; + queue->required_players = req_players; + queue->accepted_players = 0; + queue->tid_expire = INVALID_TIMER; + queue->tid_start = INVALID_TIMER; + queue->tid_requeue = INVALID_TIMER; + queue->in_ready_state = false; + + return queue; +} + +/** + * Allow a player to join a Battleground queue + * @param name: Battleground name + * @param sd: Player data + * @return @see e_bg_queue_apply_ack + */ +e_bg_queue_apply_ack bg_queue_join(const char *name, struct map_session_data *sd) +{ + if (!sd) { + ShowError("bg_queue_join: Tried to join non-existent player.\n."); + return BG_APPLY_NONE; + } + + if (!bg_queue_check_status(sd, name)) + return BG_APPLY_NONE; + + if (bg_player_is_in_bg_map(sd)) { + clif_messagecolor(&sd->bl, color_table[COLOR_LIGHT_GREEN], msg_txt(sd, 337), false, SELF); // You may not join a battleground queue when you're in a battleground map. + return BG_APPLY_NONE; + } + + std::shared_ptr bg = bg_search_name(name); + + if (!bg) { + ShowWarning("bq_queue_join: Could not find battleground \"%s\" requested by %s (AID: %d / CID: %d)\n", name, sd->status.name, sd->status.account_id, sd->status.char_id); + return BG_APPLY_INVALID_NAME; + } + + if (bg->min_lvl && sd->status.base_level < bg->min_lvl) + return BG_APPLY_PLAYER_LEVEL; // Level too low + + if (bg->max_lvl && sd->status.base_level > bg->max_lvl) + return BG_APPLY_PLAYER_LEVEL; // Level too high + + std::shared_ptr queue; + bool r; + + if (bg_queues.empty()) { + r = rnd() % 2 != 0; + + queue = bg_queue_create(bg->id, bg->required_players); + + if (!r) + queue->teama_members.push_back(sd); + else + queue->teamb_members.push_back(sd); + + sd->bg_queue = queue; + bg_queues.insert(bg_queues.begin(), queue); + return BG_APPLY_ACCEPT; + } else { + r = rnd() % 2 != 0; + + for (const auto &it : bg_queues) { + try { + queue = it; + } catch (std::out_of_range &) { + continue; + } + + if (queue->in_ready_state) + continue; + if (!r) { + if (queue->teama_members.size() != queue->required_players) { + sd->bg_queue = queue; + queue->teama_members.push_back(sd); + + if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined + bg_queue_on_ready(name, queue); + return BG_APPLY_ACCEPT; + } else if (queue->teamb_members.size() != queue->required_players) { + sd->bg_queue = queue; + queue->teamb_members.push_back(sd); + + if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined + bg_queue_on_ready(name, queue); + return BG_APPLY_ACCEPT; + } + } else { + if (queue->teamb_members.size() != queue->required_players) { + sd->bg_queue = queue; + queue->teamb_members.push_back(sd); + + if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined + bg_queue_on_ready(name, queue); + return BG_APPLY_ACCEPT; + } else if (queue->teama_members.size() != queue->required_players) { + sd->bg_queue = queue; + queue->teama_members.push_back(sd); + + if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined + bg_queue_on_ready(name, queue); + return BG_APPLY_ACCEPT; + } + } + } + } + + queue = bg_queue_create(bg->id, bg->required_players); + r = rnd() % 2 != 0; + + if (!r) + queue->teama_members.push_back(sd); + else + queue->teamb_members.push_back(sd); + + sd->bg_queue = queue; + bg_queues.insert(bg_queues.begin(), queue); + return BG_APPLY_ACCEPT; +} + +/** + * Join a party onto the same side of a Battleground + * @param name: Battleground name + * @param sd: Player who requested to join the battlegrounds + * @return @see e_bg_queue_apply_ack + */ +e_bg_queue_apply_ack bg_queue_join_party(const char *name, struct map_session_data *sd) +{ + struct party_data *p = party_search(sd->status.party_id); + + if (!p) + return BG_APPLY_INVALID_APP; // Someone has bypassed the client check for being in a party + + for (const auto &it : p->party.member) { + if (it.leader && sd->status.char_id != it.char_id) + return BG_APPLY_PARTYGUILD_LEADER; // Not the party leader + } + + std::shared_ptr bg = bg_search_name(name); + + if (bg) { + int p_online = 0; + + for (const auto &it : p->party.member) { + if (it.online) + p_online++; + } + + if (p_online > bg->max_players) + return BG_APPLY_PLAYER_COUNT; // Too many party members online + + std::vector list; + + for (const auto &it : p->party.member) { + if (list.size() == bg->max_players) + break; + + if (it.online) { + struct map_session_data *pl_sd = map_charid2sd(it.char_id); + + if (pl_sd) + list.push_back(pl_sd); + } + } + + return bg_queue_join_multi(name, sd, list); // Join as party, all on the same side of the BG + } else { + ShowWarning("clif_parse_bg_queue_apply_request: Could not find Battleground: \"%s\" requested by player: %s (AID:%d CID:%d)\n", name, sd->status.name, sd->status.account_id, sd->status.char_id); + return BG_APPLY_INVALID_NAME; // Invalid BG name + } +} + +/** + * Join a guild onto the same side of a Battleground + * @param name: Battleground name + * @param sd: Player who requested to join the battlegrounds + * @return @see e_bg_queue_apply_ack + */ +e_bg_queue_apply_ack bg_queue_join_guild(const char *name, struct map_session_data *sd) +{ + if (!sd->guild) + return BG_APPLY_INVALID_APP; // Someone has bypassed the client check for being in a guild + + if (strcmp(sd->status.name, sd->guild->master) != 0) + return BG_APPLY_PARTYGUILD_LEADER; // Not the guild leader + + std::shared_ptr bg = bg_search_name(name); + + if (bg) { + struct guild *g = guild_search(sd->status.guild_id); + int g_online = 0; + + for (const auto &it : g->member) { + if (it.online) + g_online++; + } + + if (g_online > bg->max_players) + return BG_APPLY_PLAYER_COUNT; // Too many guild members online + + std::vector list; + + for (const auto &it : g->member) { + if (list.size() == bg->max_players) + break; + + if (it.online) { + struct map_session_data *pl_sd = map_charid2sd(it.char_id); + + if (pl_sd) + list.push_back(pl_sd); + } + } + + return bg_queue_join_multi(name, sd, list); // Join as guild, all on the same side of the BG + } else { + ShowWarning("clif_parse_bg_queue_apply_request: Could not find Battleground: \"%s\" requested by player: %s (AID:%d CID:%d)\n", name, sd->status.name, sd->status.account_id, sd->status.char_id); + return BG_APPLY_INVALID_NAME; // Invalid BG name + } +} + +/** + * Join multiple players onto the same side of a Battleground + * @param name: Battleground name + * @param sd: Player who requested to join the battlegrounds + * @param list: Contains all players including the player who requested to join + * @return @see e_bg_queue_apply_ack + */ +e_bg_queue_apply_ack bg_queue_join_multi(const char *name, struct map_session_data *sd, std::vector list) +{ + if (!sd) { + ShowError("bg_queue_join_multi: Tried to join non-existent player\n."); + return BG_APPLY_NONE; + } + + if (!bg_queue_check_status(sd, name)) + return BG_APPLY_NONE; + + if (bg_player_is_in_bg_map(sd)) { + clif_messagecolor(&sd->bl, color_table[COLOR_LIGHT_GREEN], msg_txt(sd, 337), false, SELF); // You may not join a battleground queue when you're in a battleground map. + return BG_APPLY_NONE; + } + + std::shared_ptr bg = bg_search_name(name); + + if (!bg) { + ShowWarning("bq_queue_join_multi: Could not find battleground \"%s\" requested by %s (AID: %d / CID: %d)\n", name, sd->status.name, sd->status.account_id, sd->status.char_id); + return BG_APPLY_INVALID_NAME; + } + + if (bg->min_lvl && sd->status.base_level < bg->min_lvl) + return BG_APPLY_PLAYER_LEVEL; // Level too low + + if (bg->max_lvl && sd->status.base_level > bg->max_lvl) + return BG_APPLY_PLAYER_LEVEL; // Level too high + + if (bg_queues.empty()) { + std::shared_ptr queue = bg_queue_create(bg->id, bg->required_players); + bool r = rnd() % 2 != 0; + + if (!r) { + while (!list.empty() && queue->teama_members.size() < bg->required_players) { + struct map_session_data *sd2 = list.back(); + + list.pop_back(); + + if (!sd2 || sd2->bg_queue) + continue; + + if (!bg_queue_check_joinable(bg, sd2, name)) + continue; + + sd2->bg_queue = queue; + clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2); + clif_bg_queue_apply_notify(name, sd2); + queue->teama_members.insert(queue->teama_members.begin(), sd2); + } + } else { + while (!list.empty() && queue->teamb_members.size() < bg->required_players) { + struct map_session_data *sd2 = list.back(); + + list.pop_back(); + + if (!sd2 || sd2->bg_queue) + continue; + + if (!bg_queue_check_joinable(bg, sd2, name)) + continue; + + sd2->bg_queue = queue; + clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2); + clif_bg_queue_apply_notify(name, sd2); + queue->teamb_members.insert(queue->teamb_members.begin(), sd2); + } + } + + bg_queues.insert(bg_queues.begin(), queue); + + return BG_APPLY_ACCEPT; + } else { + std::shared_ptr queue; + bool r = rnd() % 2 != 0; + + for (const auto &it : bg_queues) { + try { + queue = it; + } catch (std::out_of_range &) { + continue; + } + + if (queue->in_ready_state) + continue; + + if (queue->teama_members.size() + list.size() <= bg->required_players || queue->teamb_members.size() + list.size() <= bg->required_players) { // Make sure there's enough space on one side to join as a party/guild in this queue + if (!r && queue->teama_members.size() + list.size() <= bg->required_players) { + while (!list.empty() && queue->teama_members.size() < bg->required_players) { + struct map_session_data *sd2 = list.back(); + + list.pop_back(); + + if (!sd2 || sd2->bg_queue) + continue; + + if (!bg_queue_check_joinable(bg, sd2, name)) + continue; + + sd2->bg_queue = queue; + clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2); + clif_bg_queue_apply_notify(name, sd2); + queue->teama_members.insert(queue->teama_members.begin(), sd2); + } + + if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined + bg_queue_on_ready(name, queue); + + return BG_APPLY_ACCEPT; + } else { + while (!list.empty() && queue->teamb_members.size() < bg->required_players) { + struct map_session_data *sd2 = list.back(); + + list.pop_back(); + + if (!sd2) + continue; + + if (!bg_queue_check_joinable(bg, sd2, name)) + continue; + + sd2->bg_queue = queue; + clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2); + clif_bg_queue_apply_notify(name, sd2); + queue->teamb_members.insert(queue->teamb_members.begin(), sd2); + } + } + + return BG_APPLY_ACCEPT; + } + } + + // Create a new queue if none of the existing ones are joinable for this party/guild + queue = nullptr; + queue = bg_queue_create(bg->id, bg->required_players); + r = rnd() % 2 != 0; + + if (!r) { + while (!list.empty() && queue->teama_members.size() < bg->required_players) { + struct map_session_data *sd2 = list.back(); + + list.pop_back(); + + if (!sd2 || sd2->bg_queue) + continue; + + if (!bg_queue_check_joinable(bg, sd2, name)) + continue; + + sd2->bg_queue = queue; + clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2); + clif_bg_queue_apply_notify(name, sd2); + queue->teama_members.insert(queue->teama_members.begin(), sd2); + } + } else { + while (!list.empty() && queue->teamb_members.size() < bg->required_players) { + struct map_session_data *sd2 = list.back(); + + list.pop_back(); + + if (!sd2 || sd2->bg_queue) + continue; + + if (!bg_queue_check_joinable(bg, sd2, name)) + continue; + + sd2->bg_queue = queue; + clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2); + clif_bg_queue_apply_notify(name, sd2); + queue->teamb_members.insert(queue->teamb_members.begin(), sd2); + } + } + + bg_queues.insert(bg_queues.begin(), queue); + + return BG_APPLY_ACCEPT; + } + + return BG_APPLY_RECONNECT; // Something went wrong, sends reconnect and then reapply message to client. +} + +/** + * Sub function for leaving a Battleground queue + * @param sd: Player leaving + * @param lista: List of players in queue data + * @param listb: List of players in second queue data + * @return True on success or false otherwise + */ +static bool bg_queue_leave_sub(struct map_session_data *sd, std::vector lista, std::vector listb) +{ + if (!sd) + return false; + + auto list_it = lista.begin(); + + while (list_it != lista.end()) { + struct map_session_data *player = *list_it; + + if (player == sd) { + if (sd->bg_queue->in_ready_state) { + sd->bg_queue->accepted_players = 0; + sd->bg_queue->in_ready_state = false; + sd->bg_queue_accept_state = false; + } + + list_it = lista.erase(list_it); + + if (lista.empty() && listb.empty()) { // If there are no players left in the queue, discard it + auto queue_it = bg_queues.begin(); + + while (queue_it != bg_queues.end()) { + std::shared_ptr q = *queue_it; + + if (sd->bg_queue == q) { + if (q->tid_requeue != INVALID_TIMER && get_timer(q->tid_requeue)) { + delete_timer(q->tid_requeue, bg_on_ready_loopback); + q->tid_requeue = INVALID_TIMER; + } + + queue_it = bg_queues.erase(queue_it); + } + } + } + + sc_start(nullptr, &sd->bl, SC_ENTRY_QUEUE_APPLY_DELAY, 100, 1, 60000); + sd->bg_queue = nullptr; + return true; + } else { + list_it++; + } + } + + return false; +} + +/** + * Leave a Battleground queue + * @param sd: Player data + * @return True on success or false otherwise + */ +bool bg_queue_leave(struct map_session_data *sd) +{ + if (!sd || !sd->bg_queue) + return false; + + if (!bg_queue_leave_sub(sd, sd->bg_queue->teama_members, sd->bg_queue->teamb_members) && !bg_queue_leave_sub(sd, sd->bg_queue->teamb_members, sd->bg_queue->teama_members)) { + ShowError("bg_queue_leave: Couldn't find player %s in battlegrounds queue.\n", sd->status.name); + return false; + } else + return true; +} + +/** + * Send packets to all clients in queue to notify them that the battleground is ready to be joined + * @param name: Battleground name + * @param queue: Battleground queue + * @return True on success or false otherwise + */ +bool bg_queue_on_ready(const char *name, std::shared_ptr queue) +{ + std::shared_ptr bg = battleground_db.find(queue->id); + + if (!bg) { + ShowError("bg_queue_on_ready: Couldn't find battleground ID %d in battlegrounds database.\n", queue->id); + return false; + } + + queue->accepted_players = 0; // Reset the counter just in case. + + if (queue->teama_members.size() != queue->required_players || queue->teamb_members.size() != queue->required_players) + return false; // Return players to the queue and stop reapplying the timer + + s_battleground_map *bgmap = nullptr; + + for (auto &it : bg->maps) { + if (!it.isReserved) { + it.isReserved = true; + bgmap = ⁢ + queue->map = ⁢ + break; + } + } + + if (!bgmap) { // All the battleground maps are reserved. Set a timer to check for an open battleground every 10 seconds. + queue->tid_requeue = add_timer(gettick() + 10000, bg_on_ready_loopback, 0, (intptr_t)queue.get()); + return false; + } + + queue->in_ready_state = true; + queue->tid_expire = add_timer(gettick() + 20000, bg_on_ready_expire, 0, (intptr_t)queue.get()); + + for (const auto &sd : queue->teama_members) + clif_bg_queue_lobby_notify(name, sd); + + for (const auto &sd : queue->teamb_members) + clif_bg_queue_lobby_notify(name, sd); + + return true; +} + +/** + * Update the Battleground queue when the player accepts the invite + * @param queue: Battleground queue + * @param sd: Player data + */ +void bg_queue_on_accept_invite(std::shared_ptr queue, struct map_session_data *sd) +{ + nullpo_retv(sd); + + sd->bg_queue_accept_state = true; + queue->accepted_players++; + clig_bg_queue_ack_lobby(true, map_mapid2mapname(queue->map->mapid), map_mapid2mapname(queue->map->mapid), sd); + + if (queue->accepted_players == queue->required_players * 2) { + queue->tid_start = add_timer(gettick() + battleground_db.find(queue->id)->start_delay * 1000, bg_on_ready_start, 0, (intptr_t)queue.get()); + + if (queue->tid_expire != INVALID_TIMER && get_timer(queue->tid_expire)) { + delete_timer(queue->tid_expire, bg_on_ready_expire); + queue->tid_expire = INVALID_TIMER; + } + } +} + +/** + * Begin the Battleground from the given queue + * @param queue: Battleground queue + */ +void bg_queue_start_battleground(std::shared_ptr queue) +{ + if (queue->tid_start != INVALID_TIMER && get_timer(queue->tid_start)) { + delete_timer(queue->tid_start, bg_on_ready_start); + queue->tid_start = INVALID_TIMER; + } + + std::shared_ptr bg = battleground_db.find(queue->id); + + if (!bg) { + queue->map->isReserved = false; // Remove reservation to free up for future queue + queue->map = nullptr; + ShowError("bg_queue_start_battleground: Could not find battleground ID %d in battlegrounds database.\n", queue->id); + return; + } + + uint16 map_idx = map_id2index(queue->map->mapid); + int bg_team_1 = bg_create(map_idx, &queue->map->team1); + int bg_team_2 = bg_create(map_idx, &queue->map->team2); + + for (const auto &sd : queue->teama_members) { + sd->bg_queue = nullptr; + sd->bg_queue_accept_state = false; + clif_bg_queue_entry_init(sd); + bg_team_join(bg_team_1, sd, true); + } + + for (const auto &sd : queue->teamb_members) { + sd->bg_queue = nullptr; + sd->bg_queue_accept_state = false; + clif_bg_queue_entry_init(sd); + bg_team_join(bg_team_2, sd, true); + } + + mapreg_setreg(add_str(queue->map->team1.bg_id_var.c_str()), bg_team_1); + mapreg_setreg(add_str(queue->map->team2.bg_id_var.c_str()), bg_team_2); + npc_event_do(queue->map->bgcallscript.c_str()); + queue->teama_members.clear(); + queue->teamb_members.clear(); + queue->teama_members.shrink_to_fit(); + queue->teamb_members.shrink_to_fit(); + + auto queue_it = bg_queues.begin(); + + while (queue_it != bg_queues.end()) { + if (*queue_it == queue) + queue_it = bg_queues.erase(queue_it); + } + + return; +} + +/** + * Initialize the Battleground data + */ void do_init_battleground(void) { - bg_team_db = idb_alloc(DB_OPT_RELEASE_DATA); + if (battle_config.feature_bgqueue) + battleground_db.load(); + add_timer_func_list(bg_send_xy_timer, "bg_send_xy_timer"); + add_timer_func_list(bg_on_ready_loopback, "bg_on_ready_loopback"); + add_timer_func_list(bg_on_ready_expire, "bg_on_ready_expire"); + add_timer_func_list(bg_on_ready_start, "bg_on_ready_start"); add_timer_interval(gettick() + battle_config.bg_update_interval, bg_send_xy_timer, 0, 0, battle_config.bg_update_interval); } +/** + * Clear the Battleground data from memory + */ void do_final_battleground(void) { - bg_team_db->destroy(bg_team_db, NULL); } diff --git a/src/map/battleground.hpp b/src/map/battleground.hpp index 9ee9165b81..b761ada07d 100644 --- a/src/map/battleground.hpp +++ b/src/map/battleground.hpp @@ -4,42 +4,141 @@ #ifndef BATTLEGROUND_HPP #define BATTLEGROUND_HPP +#include +#include +#include + #include "../common/cbasetypes.hpp" +#include "../common/database.hpp" #include "../common/mmo.hpp" // struct party #define MAX_BG_MEMBERS 30 -struct battleground_member_data { +struct s_battleground_member_data { unsigned short x, y; struct map_session_data *sd; unsigned afk : 1; + struct point entry_point; ///< Battleground queue entry point }; -struct battleground_data { - unsigned int bg_id; - unsigned char count; - struct battleground_member_data members[MAX_BG_MEMBERS]; - // BG Cementery - unsigned short mapindex, x, y; - // Logout Event - char logout_event[EVENT_NAME_LENGTH]; - char die_event[EVENT_NAME_LENGTH]; +struct s_battleground_data { + int id; ///< Battleground ID + std::vector members; ///< List of players in battleground + struct point cemetery; ///< Respawn point for players who die + std::string logout_event; ///< NPC Event to call on log out events + std::string die_event; ///< NPC Event to call on death events }; +struct s_battleground_team { + int16 warp_x, warp_y; ///< Team respawn coordinates + std::string quit_event, ///< Team NPC Event to call on log out events + death_event, ///< Team NPC Event to call on death events + bg_id_var; ///< Team NPC variable name +}; + +struct s_battleground_map { + int id; ///< Battleground ID + int16 mapid; ///< ID of the map + s_battleground_team team1, team2; ///< Team data + std::string bgcallscript; ///< Script to be called when players join the battleground + bool isReserved; ///< Reserve BG maps that are used so that the system won't create multiple BG instances on the same map +}; + +/// Battlegrounds client interface queue system [MasterOfMuppets] +struct s_battleground_queue { + int id; ///< Battlegrounds database ID + std::vector teama_members; ///< List of members on team A + std::vector teamb_members; ///< List of members on team B + int required_players; ///< Amount of players required on each side to start + int max_players; ///< Maximum amount of players on each side + int accepted_players; ///< Amount of players who accepted the offer to enter the battleground + bool in_ready_state; ///< Is this BG queue waiting for players to enter the BG? + int tid_expire; ///< Timer ID associated with the time out at the ready to enter window + int tid_start; ///< Timer ID associated with the start delay + int tid_requeue; ///< Timer ID associated with requeuing this group if all BG maps are reserved + s_battleground_map *map; ///< Map this BG queue has been assigned to +}; + +struct s_battleground_type { + int id; ///< Battlegrounds database ID + std::string name; ///< Name of the battleground type + int required_players; ///< Amount of players required on each side to start + int max_players; ///< Maximum amount of players on each side + int min_lvl; ///< Minimum level to participate in this battleground type + int max_lvl; ///< Maximum level to participate in this battleground type + std::vector maps; ///< List of battleground locations + uint32 deserter_time; ///< Amount of time a player is marked deserter (seconds) + uint32 start_delay; ///< Amount of time before the start message is sent to players (seconds) +}; + +/// Enum of responses when applying for a Battleground +enum e_bg_queue_apply_ack : uint16 { + BG_APPLY_NONE = 0, + BG_APPLY_ACCEPT, ///< Accept + BG_APPLY_QUEUE_FINISHED, ///< Queuing has finished + BG_APPLY_INVALID_NAME, ///< Invalid name of Battleground + BG_APPLY_INVALID_APP, ///< Invalid application + BG_APPLY_PLAYER_COUNT, ///< Too many players in party/guild + BG_APPLY_PLAYER_LEVEL, ///< Level too low/high + BG_APPLY_DUPLICATE, ///< Duplicate application + BG_APPLY_RECONNECT, ///< Reconnect then apply + BG_APPLY_PARTYGUILD_LEADER, ///< Only party/guild leader can apply + BG_APPLY_PLAYER_CLASS, ///< Your class can't apply +}; + +/// Enum of script command bg_info types +enum e_bg_info : uint16 { + BG_INFO_ID = 0, + BG_INFO_REQUIRED_PLAYERS, + BG_INFO_MAX_PLAYERS, + BG_INFO_MIN_LEVEL, + BG_INFO_MAX_LEVEL, + BG_INFO_MAPS, + BG_INFO_DESERTER_TIME, +}; + +class BattlegroundDatabase : public TypesafeYamlDatabase { +public: + BattlegroundDatabase() : TypesafeYamlDatabase("BATTLEGROUND_DB", 1) { + + } + + const std::string getDefaultLocation(); + uint64 parseBodyNode(const YAML::Node& node); +}; + +extern BattlegroundDatabase battleground_db; +extern std::unordered_map> bg_team_db; + +std::shared_ptr bg_search_name(const char *name); +void bg_send_dot_remove(struct map_session_data *sd); +int bg_team_get_id(struct block_list *bl); +struct map_session_data *bg_getavailablesd(s_battleground_data *bg); + +bool bg_queue_reservation(const char *name, bool state); +#define bg_queue_reserve(name) (bg_queue_reservation(name, true)) +#define bg_queue_unbook(name) (bg_queue_reservation(name, false)) + +int bg_create(uint16 mapindex, s_battleground_team* team); +bool bg_team_join(int bg_id, struct map_session_data *sd, bool is_queue); +bool bg_team_delete(int bg_id); +int bg_team_leave(struct map_session_data *sd, bool quit, bool deserter); +bool bg_team_warp(int bg_id, unsigned short mapindex, short x, short y); +bool bg_player_is_in_bg_map(struct map_session_data *sd); +bool bg_queue_check_joinable(std::shared_ptr bg, struct map_session_data *sd, const char *name); +std::shared_ptr bg_queue_create(int bg_id, int req_players); +e_bg_queue_apply_ack bg_queue_join(const char *name, struct map_session_data *sd); +e_bg_queue_apply_ack bg_queue_join_party(const char *name, struct map_session_data *sd); +e_bg_queue_apply_ack bg_queue_join_guild(const char *name, struct map_session_data *sd); +e_bg_queue_apply_ack bg_queue_join_multi(const char *name, struct map_session_data *sd, std::vector list); +bool bg_queue_leave(struct map_session_data *sd); +bool bg_queue_on_ready(const char *name, std::shared_ptr queue); +void bg_queue_on_accept_invite(std::shared_ptr queue, struct map_session_data *sd); +void bg_queue_start_battleground(std::shared_ptr queue); +bool bg_member_respawn(struct map_session_data *sd); +void bg_send_message(struct map_session_data *sd, const char *mes, int len); + void do_init_battleground(void); void do_final_battleground(void); -struct battleground_data* bg_team_search(int bg_id); -int bg_send_dot_remove(struct map_session_data *sd); -int bg_team_get_id(struct block_list *bl); -struct map_session_data* bg_getavailablesd(struct battleground_data *bg); - -int bg_create(unsigned short mapindex, short rx, short ry, const char *ev, const char *dev); -int bg_team_join(int bg_id, struct map_session_data *sd); -int bg_team_delete(int bg_id); -int bg_team_leave(struct map_session_data *sd, int flag); -int bg_team_warp(int bg_id, unsigned short mapindex, short x, short y); -int bg_member_respawn(struct map_session_data *sd); -int bg_send_message(struct map_session_data *sd, const char *mes, int len); - #endif /* BATTLEGROUND_HPP */ diff --git a/src/map/clif.cpp b/src/map/clif.cpp index fad7eede6b..379c12d5d9 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -20,6 +20,7 @@ #include "../common/socket.hpp" #include "../common/strlib.hpp" #include "../common/timer.hpp" +#include "../common/utilities.hpp" #include "../common/utils.hpp" #include "achievement.hpp" @@ -57,6 +58,8 @@ #include "unit.hpp" #include "vending.hpp" +using namespace rathena; + static inline uint32 client_tick( t_tick tick ){ return (uint32)tick; } @@ -391,7 +394,7 @@ int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target struct map_session_data *sd, *tsd; struct party_data *p = NULL; struct guild *g = NULL; - struct battleground_data *bg = NULL; + std::shared_ptr bg; int x0 = 0, x1 = 0, y0 = 0, y1 = 0, fd; struct s_mapiterator* iter; @@ -603,9 +606,9 @@ int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target case BG_SAMEMAP_WOS: case BG: case BG_WOS: - if( sd && sd->bg_id && (bg = bg_team_search(sd->bg_id)) != NULL ) + if( sd && sd->bg_id && (bg = util::umap_find(bg_team_db, sd->bg_id))) { - for( i = 0; i < MAX_BG_MEMBERS; i++ ) + for( i = 0; i < bg->members.size(); i++ ) { if( (sd = bg->members[i].sd) == NULL || !(fd = sd->fd) ) continue; @@ -17374,7 +17377,7 @@ void clif_bg_xy_remove(struct map_session_data *sd) /// Notifies clients of a battleground message. /// 02DC .W .L .24B .?B (ZC_BATTLEFIELD_CHAT) -void clif_bg_message( struct battleground_data *bg, int src_id, const char *name, const char *mes, int len ){ +void clif_bg_message( struct s_battleground_data *bg, int src_id, const char *name, const char *mes, int len ){ struct map_session_data *sd = bg_getavailablesd( bg ); if( sd == nullptr ){ @@ -17467,6 +17470,201 @@ void clif_sendbgemblem_single(int fd, struct map_session_data *sd) WFIFOSET(fd,packet_len(0x2dd)); } +/// Battlegrounds queue incoming apply request from client. +/// Queue types: 1 solo queue, 2 party queue, 4 guild queue. +/// 0x8d7 .W .24B (CZ_REQ_ENTRY_QUEUE_APPLY) +void clif_parse_bg_queue_apply_request(int fd, struct map_session_data *sd) +{ + if (!battle_config.feature_bgqueue) + return; + + nullpo_retv(sd); + + short type = RFIFOW(fd,2); + char name[NAME_LENGTH]; + e_bg_queue_apply_ack result; + + safestrncpy(name, RFIFOCP(fd, 4), NAME_LENGTH); + + if (sd->bg_queue) { + ShowWarning("clif_parse_bg_queue_apply_request: Received duplicate queue application: %d from player %s (AID:%d CID:%d).\n", type, sd->status.name, sd->status.account_id, sd->status.char_id); + clif_bg_queue_apply_result(BG_APPLY_DUPLICATE, name, sd); // Duplicate application warning + return; + } else if (type == 1) // Solo + result = bg_queue_join(name, sd); + else if (type == 2) // Party + result = bg_queue_join_party(name, sd); + else if (type == 4) // Guild + result = bg_queue_join_guild(name, sd); + else { + ShowWarning("clif_parse_bg_queue_apply_request: Received invalid queue type: %d from player %s (AID:%d CID:%d).\n", type, sd->status.name, sd->status.account_id, sd->status.char_id); + clif_bg_queue_apply_result(BG_APPLY_INVALID_APP, name, sd); // Someone sent an invalid queue type packet + return; + } + + clif_bg_queue_apply_result(result, name, sd); + if (result == BG_APPLY_ACCEPT) + clif_bg_queue_apply_notify(name, sd); +} + +/// Outgoing battlegrounds queue apply result. +/// Result types: @see e_bg_queue_apply_ack +/// 0x8d8 .B .24B (ZC_ACK_ENTRY_QUEUE_APPLY) +void clif_bg_queue_apply_result(e_bg_queue_apply_ack result, const char *name, struct map_session_data *sd) +{ + nullpo_retv(sd); + + int fd = sd->fd; + + WFIFOHEAD(fd, packet_len(0x8d8)); + WFIFOW(fd,0) = 0x8d8; + WFIFOB(fd,2) = result; + safestrncpy(WFIFOCP(fd,3), name, NAME_LENGTH); + WFIFOSET(fd, packet_len(0x8d8)); +} + +/// Outgoing battlegrounds queue apply notification. +/// Sends a notification at the start of the battlegrounds queue and is also used to update the queue number. +/// 0x8d9 .24B .L (ZC_NOTIFY_ENTRY_QUEUE_APPLY) +void clif_bg_queue_apply_notify(const char *name, struct map_session_data *sd) +{ + nullpo_retv(sd); + + std::shared_ptr queue = sd->bg_queue; + + if (!queue) { + ShowError("clif_bg_queue_apply_notify: Player is not in a battleground queue.\n"); + return; + } + + int fd = sd->fd; + + WFIFOHEAD(fd, packet_len(0x8d9)); + WFIFOW(fd,0) = 0x8d9; + safestrncpy(WFIFOCP(fd,2), name, NAME_LENGTH); + WFIFOL(fd,2+NAME_LENGTH) = queue->teama_members.size() + queue->teamb_members.size(); + WFIFOSET(fd, packet_len(0x8d9)); +} + +/// Battlegrounds queue outgoing cancel result. +/// 0x8db .B .24B (ZC_ACK_ENTRY_QUEUE_CANCEL) +void clif_bg_queue_cancel_result(bool success, const char *name, struct map_session_data *sd) +{ + nullpo_retv(sd); + + int fd = sd->fd; + + WFIFOHEAD(fd, packet_len(0x8d8)); + WFIFOW(fd,0) = 0x8db; + WFIFOB(fd,2) = success; + safestrncpy(WFIFOCP(fd,3), name, NAME_LENGTH); + WFIFOSET(fd, packet_len(0x8d8)); +} + +/// Battlegrounds queue incoming cancel request from client. +/// 0x8da .24B (CZ_REQ_ENTRY_QUEUE_CANCEL) +void clif_parse_bg_queue_cancel_request(int fd, struct map_session_data *sd) +{ + if (!battle_config.feature_bgqueue) + return; + + nullpo_retv(sd); + + bool success; + + if (sd->bg_queue) { + if (sd->bg_queue->in_ready_state) + return; // Make the cancel button do nothing if the entry window is open. Otherwise it'll crash the game when you click on both the queue status and entry status window. + else + success = bg_queue_leave(sd); + } else { + ShowWarning("clif_parse_bg_queue_cancel_request: Player trying to request leaving non-existent queue with name: %s (AID:%d CID:%d).\n", sd->status.name, sd->status.account_id, sd->status.char_id); + success = false; + } + + char name[NAME_LENGTH]; + + safestrncpy( name, RFIFOCP( fd, 2 ), NAME_LENGTH ); + + clif_bg_queue_cancel_result(success, name, sd); +} + +/// Battleground is ready to be joined, send a window asking for players to accept or decline. +/// 0x8df .24B .24B (ZC_NOTIFY_LOBBY_ADMISSION) +void clif_bg_queue_lobby_notify(const char *name, struct map_session_data *sd) +{ + nullpo_retv(sd); + + int fd = sd->fd; + + WFIFOHEAD(fd, packet_len(0x8df)); + WFIFOW(fd,0) = 0x8df; + safestrncpy(WFIFOCP(fd,2), name, NAME_LENGTH); + safestrncpy(WFIFOCP(fd,2+NAME_LENGTH), name, NAME_LENGTH); + WFIFOSET(fd, packet_len(0x8df)); +} + +/// Incoming packet from client telling server whether player wants to enter battleground or cancel. +/// Result types: 1(Accept), 2(Decline). +/// 0x8e0 .B .24B .24B (CZ_REPLY_LOBBY_ADMISSION) +void clif_parse_bg_queue_lobby_reply(int fd, struct map_session_data *sd) +{ + nullpo_retv(sd); + + if(sd->bg_queue) { + uint8 result = RFIFOB(fd, 2); + + if(result == 1) { // Accept + bg_queue_on_accept_invite(sd->bg_queue, sd); + } else if(result == 2) { // Decline + bg_queue_leave(sd); + clif_bg_queue_entry_init(sd); + } + } +} + +/// Plays a gong sound, signaling that someone has accepted the invite to enter a battleground. +/// 0x8e1 .B .24B .24B (ZC_REPLY_ACK_LOBBY_ADMISSION) +void clig_bg_queue_ack_lobby(bool result, const char *name, const char *lobbyname, struct map_session_data *sd) +{ + nullpo_retv(sd); + + int fd = sd->fd; + + WFIFOHEAD(fd, packet_len(0x8e1)); + WFIFOW(fd,0) = 0x8e1; + WFIFOB(fd,2) = result; + safestrncpy(WFIFOCP(fd,3), name, NAME_LENGTH); + safestrncpy(WFIFOCP(fd,3+NAME_LENGTH), lobbyname, NAME_LENGTH); + WFIFOSET(fd, packet_len(0x8e1)); +} + +/// Battlegrounds queue incoming queue number request from client. +/// 0x90a .24B (CZ_REQ_ENTRY_QUEUE_RANKING) +void clif_parse_bg_queue_request_queue_number(int fd, struct map_session_data *sd) +{ + nullpo_retv(sd); + + char name[NAME_LENGTH]; + + safestrncpy( name, RFIFOCP(fd, 2), NAME_LENGTH ); + + clif_bg_queue_apply_notify(name, sd); +} + +/// Silently removes all the battlegrounds stuff client side so that you will open the first BG window when you press battle on the interface. +/// Send this when a player joins a battleground so that it will remove all the queue stuff upon warping in. +/// 0x90e (ZC_ENTRY_QUEUE_INIT) +void clif_bg_queue_entry_init(struct map_session_data *sd) +{ + nullpo_retv(sd); + + int fd = sd->fd; + + WFIFOHEAD(fd, packet_len(0x90e)); + WFIFOW(fd,0) = 0x90e; + WFIFOSET(fd, packet_len(0x90e)); +} /// Custom Fonts (ZC_NOTIFY_FONT). /// 02ef .L .W diff --git a/src/map/clif.hpp b/src/map/clif.hpp index 547341caba..b8f57aa40b 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -34,7 +34,7 @@ struct s_vending; struct party; struct party_data; struct guild; -struct battleground_data; +struct s_battleground_data; struct quest; struct party_booking_ad_info; struct sale_item_data; @@ -42,6 +42,7 @@ struct mail_message; struct achievement; struct guild_log_entry; enum e_guild_storage_log : uint16; +enum e_bg_queue_apply_ack : uint16; enum e_PacketDBVersion { // packet DB MIN_PACKET_DB = 0x064, @@ -818,12 +819,19 @@ void clif_guild_xy_remove(struct map_session_data *sd); void clif_bg_hp(struct map_session_data *sd); void clif_bg_xy(struct map_session_data *sd); void clif_bg_xy_remove(struct map_session_data *sd); -void clif_bg_message(struct battleground_data *bg, int src_id, const char *name, const char *mes, int len); +void clif_bg_message(struct s_battleground_data *bg, int src_id, const char *name, const char *mes, int len); void clif_bg_updatescore(int16 m); void clif_bg_updatescore_single(struct map_session_data *sd); void clif_sendbgemblem_area(struct map_session_data *sd); void clif_sendbgemblem_single(int fd, struct map_session_data *sd); +// Battleground Queue +void clif_bg_queue_apply_result(e_bg_queue_apply_ack result, const char *name, struct map_session_data *sd); +void clif_bg_queue_apply_notify(const char *name, struct map_session_data *sd); +void clif_bg_queue_entry_init(struct map_session_data *sd); +void clif_bg_queue_lobby_notify(const char *name, struct map_session_data *sd); +void clig_bg_queue_ack_lobby(bool result, const char *name, const char *lobbyname, struct map_session_data *sd); + // Instancing void clif_instance_create(unsigned short instance_id, int num); void clif_instance_changewait(unsigned short instance_id, int num); diff --git a/src/map/clif_packetdb.hpp b/src/map/clif_packetdb.hpp index 17d0bdd8db..d5ffc33b14 100644 --- a/src/map/clif_packetdb.hpp +++ b/src/map/clif_packetdb.hpp @@ -1968,7 +1968,19 @@ parseable_packet(0x08fb,6,NULL,2); parseable_packet(0x0907,5,clif_parse_MoveItem,2,4); packet(0x0908,5); - parseable_packet(0x08d7,28,NULL,2,4); + parseable_packet(0x08D7,28,clif_parse_bg_queue_apply_request,2,4); + packet(0x08D8,27); + packet(0x08D9,30); + parseable_packet(0x08DA,26,clif_parse_bg_queue_cancel_request,2); + packet(0x08DB,27); + packet(0x08DC,26); + parseable_packet(0x08DD,27,clif_parse_dull,2,3); + packet(0x08DE,27); + packet(0x08DF,50); + parseable_packet(0x08E0,51,clif_parse_bg_queue_lobby_reply,2,3,27); + packet(0x08E1,51); + parseable_packet(0x090A,26,clif_parse_bg_queue_request_queue_number,2); + packet(0x090E,2); packet(0x0977,14); //Monster HP Bar parseable_packet(0x0916,26,clif_parse_GuildInvite2,2); parseable_packet(0x091d,41,clif_parse_PartyBookingRegisterReq,2,4,6); diff --git a/src/map/map-server.vcxproj b/src/map/map-server.vcxproj index fe062a23c8..a26460272b 100644 --- a/src/map/map-server.vcxproj +++ b/src/map/map-server.vcxproj @@ -296,6 +296,7 @@ + diff --git a/src/map/map.cpp b/src/map/map.cpp index 29044b0cdc..039bb50cc9 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -2058,8 +2058,11 @@ int map_quit(struct map_session_data *sd) { if (sd->npc_id) npc_event_dequeue(sd); - if( sd->bg_id ) - bg_team_leave(sd,1); + if (sd->bg_id) + bg_team_leave(sd, true, true); + + if (sd->bg_queue != nullptr) + bg_queue_leave(sd); if( sd->status.clan_id ) clan_member_left(sd); @@ -5242,9 +5245,9 @@ int do_init(int argc, char *argv[]) do_init_elemental(); do_init_quest(); do_init_achievement(); + do_init_battleground(); do_init_npc(); do_init_unit(); - do_init_battleground(); do_init_duel(); do_init_vending(); do_init_buyingstore(); diff --git a/src/map/mob.hpp b/src/map/mob.hpp index f9e3a8b846..96ed07def7 100644 --- a/src/map/mob.hpp +++ b/src/map/mob.hpp @@ -219,7 +219,7 @@ struct mob_data { int level; int target_id,attacked_id,norm_attacked_id; int areanpc_id; //Required in OnTouchNPC (to avoid multiple area touchs) - unsigned int bg_id; // BattleGround System + int bg_id; // BattleGround System t_tick next_walktime,last_thinktime,last_linktime,last_pcneartime,dmgtick; short move_fail_count; diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 3701c40024..a18fd82e60 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -1529,6 +1529,10 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_ sd->bonus_script.head = NULL; sd->bonus_script.count = 0; + // Initialize BG queue pointer + sd->bg_queue = nullptr; + sd->bg_queue_accept_state = false; + #if PACKETVER >= 20150513 sd->hatEffectIDs = NULL; sd->hatEffectCount = 0; @@ -5758,6 +5762,9 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in instance_addusers(new_map_instance_id); } + if (sd->bg_id && !mapdata->flag[MF_BATTLEGROUND]) // Moving to a map that isn't a Battlegrounds + bg_team_leave(sd, false, true); + sd->state.pmap = sd->bl.m; if (sd->sc.count) { // Cancel some map related stuff. if (sd->sc.data[SC_JAILED]) @@ -8306,10 +8313,13 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) return 1|8; } else if( sd->bg_id ) { - struct battleground_data *bg = bg_team_search(sd->bg_id); - if( bg && bg->mapindex > 0 ) { // Respawn by BG - sd->respawn_tid = add_timer(tick+1000, pc_respawn_timer, sd->bl.id, 0); - return 1|8; + std::shared_ptr bg = util::umap_find(bg_team_db, sd->bg_id); + + if (bg) { + if (bg->cemetery.map > 0) { // Respawn by BG + sd->respawn_tid = add_timer(tick + 1000, pc_respawn_timer, sd->bl.id, 0); + return 1|8; + } } } diff --git a/src/map/pc.hpp b/src/map/pc.hpp index fca4847019..bb87ab8e5d 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -4,12 +4,14 @@ #ifndef PC_HPP #define PC_HPP +#include #include #include "../common/mmo.hpp" // JOB_*, MAX_FAME_LIST, struct fame_list, struct mmo_charstatus #include "../common/strlib.hpp"// StringBuf #include "../common/timer.hpp" +#include "battleground.hpp" #include "buyingstore.hpp" // struct s_buyingstore #include "clif.hpp" //e_wip_block #include "itemdb.hpp" // MAX_ITEMGROUP @@ -623,6 +625,10 @@ struct map_session_data { bool changed; // if true, should sync with charserver on next mailbox request } mail; + // Battlegrounds queue system [MasterOfMuppets] + std::shared_ptr bg_queue; + bool bg_queue_accept_state; // Set this to true when someone has accepted the invite to join BGs + //Quest log system int num_quests; ///< Number of entries in quest_log int avail_quests; ///< Number of Q_ACTIVE and Q_INACTIVE entries in quest log (index of the first Q_COMPLETE entry) @@ -651,7 +657,7 @@ struct map_session_data { int debug_line; const char* debug_func; - unsigned int bg_id; + int bg_id; #ifdef SECURE_NPCTIMEOUT /** diff --git a/src/map/script.cpp b/src/map/script.cpp index d41f07b76d..3785685d11 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -19662,9 +19662,10 @@ BUILDIN_FUNC(waitingroom2bg) { struct npc_data *nd; struct chat_data *cd; - const char *map_name, *ev = "", *dev = ""; - int x, y, mapindex = 0, bg_id; + const char *map_name; + int mapindex = 0, bg_id; unsigned char i,c=0; + struct s_battleground_team team; if( script_hasdata(st,7) ) nd = npc_name2id(script_getstr(st,7)); @@ -19684,17 +19685,20 @@ BUILDIN_FUNC(waitingroom2bg) return SCRIPT_CMD_SUCCESS; } - x = script_getnum(st,3); - y = script_getnum(st,4); - if(script_hasdata(st,5)) - ev = script_getstr(st,5); // Logout Event - if(script_hasdata(st,6)) - dev = script_getstr(st,6); // Die Event + team.warp_x = script_getnum(st,3); + team.warp_y = script_getnum(st,4); + if (script_hasdata(st,5)) { + team.quit_event = script_getstr(st,5); // Logout Event + check_event(st, team.quit_event.c_str()); + } else + team.quit_event = ""; + if (script_hasdata(st,6)) { + team.death_event = script_getstr(st,6); // Die Event + check_event(st, team.death_event.c_str()); + } else + team.death_event = ""; - check_event(st, ev); - check_event(st, dev); - - if( (bg_id = bg_create(mapindex, x, y, ev, dev)) == 0 ) + if( (bg_id = bg_create(mapindex, &team)) == 0 ) { // Creation failed script_pushint(st,0); return SCRIPT_CMD_SUCCESS; @@ -19702,7 +19706,7 @@ BUILDIN_FUNC(waitingroom2bg) for (i = 0; i < cd->users; i++) { // Only add those who are in the chat room struct map_session_data *sd; - if( (sd = cd->usersd[i]) != NULL && bg_team_join(bg_id, sd) ){ + if( (sd = cd->usersd[i]) != NULL && bg_team_join(bg_id, sd, false) ){ mapreg_setreg(reference_uid(add_str("$@arenamembers"), c), sd->bl.id); ++c; } @@ -19719,11 +19723,10 @@ BUILDIN_FUNC(waitingroom2bg_single) struct npc_data *nd; struct chat_data *cd; struct map_session_data *sd; - struct battleground_data *bg; - int x, y, mapindex, bg_id; + int x, y, mapindex, bg_id = script_getnum(st,2); + std::shared_ptr bg = util::umap_find(bg_team_db, bg_id); - bg_id = script_getnum(st,2); - if ((bg = bg_team_search(bg_id)) == NULL) { + if (!bg) { script_pushint(st, false); return SCRIPT_CMD_SUCCESS; } @@ -19737,9 +19740,9 @@ BUILDIN_FUNC(waitingroom2bg_single) y = script_getnum(st, 5); } else { - mapindex = bg->mapindex; - x = bg->x; - y = bg->y; + mapindex = bg->cemetery.map; + x = bg->cemetery.x; + y = bg->cemetery.y; } nd = npc_name2id(script_getstr(st,6)); @@ -19750,7 +19753,7 @@ BUILDIN_FUNC(waitingroom2bg_single) if( (sd = cd->usersd[0]) == NULL ) return SCRIPT_CMD_SUCCESS; - if( bg_team_join(bg_id, sd) && pc_setpos(sd, mapindex, x, y, CLR_TELEPORT) == SETPOS_OK) + if( bg_team_join(bg_id, sd, false) && pc_setpos(sd, mapindex, x, y, CLR_TELEPORT) == SETPOS_OK) { script_pushint(st, true); } @@ -19765,8 +19768,9 @@ BUILDIN_FUNC(waitingroom2bg_single) /// *bg_create("",,{,"",""}); /// @author [secretdataz] BUILDIN_FUNC(bg_create) { - const char *map_name, *ev = "", *dev = ""; - int x, y, mapindex = 0; + const char *map_name; + int mapindex = 0; + struct s_battleground_team team; map_name = script_getstr(st, 2); if (strcmp(map_name, "-") != 0 && (mapindex = mapindex_name2id(map_name)) == 0) @@ -19775,17 +19779,20 @@ BUILDIN_FUNC(bg_create) { return SCRIPT_CMD_SUCCESS; } - x = script_getnum(st, 3); - y = script_getnum(st, 4); - if(script_hasdata(st, 5)) - ev = script_getstr(st, 5); // Logout Event - if(script_hasdata(st, 6)) - dev = script_getstr(st, 6); // Die Event + team.warp_x = script_getnum(st,3); + team.warp_y = script_getnum(st,4); + if (script_hasdata(st,5)) { + team.quit_event = script_getstr(st,5); // Logout Event + check_event(st, team.quit_event.c_str()); + } else + team.quit_event = ""; + if (script_hasdata(st,6)) { + team.death_event = script_getstr(st,6); // Die Event + check_event(st, team.death_event.c_str()); + } else + team.death_event = ""; - check_event(st, ev); - check_event(st, dev); - - script_pushint(st, bg_create(mapindex, x, y, ev, dev)); + script_pushint(st, bg_create(mapindex, &team)); return SCRIPT_CMD_SUCCESS; } @@ -19797,11 +19804,10 @@ BUILDIN_FUNC(bg_create) { BUILDIN_FUNC(bg_join) { const char* map_name; struct map_session_data *sd; - struct battleground_data *bg; - int x, y, bg_id, mapindex; + int x, y, mapindex, bg_id = script_getnum(st, 2); + std::shared_ptr bg = util::umap_find(bg_team_db, bg_id); - bg_id = script_getnum(st, 2); - if ((bg = bg_team_search(bg_id)) == NULL) { + if (!bg) { script_pushint(st, false); return SCRIPT_CMD_SUCCESS; } @@ -19814,9 +19820,9 @@ BUILDIN_FUNC(bg_join) { x = script_getnum(st, 4); y = script_getnum(st, 5); } else { - mapindex = bg->mapindex; - x = bg->x; - y = bg->y; + mapindex = bg->cemetery.map; + x = bg->cemetery.x; + y = bg->cemetery.y; } if (!script_charid2sd(6, sd)) { @@ -19824,7 +19830,7 @@ BUILDIN_FUNC(bg_join) { return SCRIPT_CMD_FAILURE; } - if (bg_team_join(bg_id, sd) && pc_setpos(sd, mapindex, x, y, CLR_TELEPORT) == SETPOS_OK) + if (bg_team_join(bg_id, sd, false) && pc_setpos(sd, mapindex, x, y, CLR_TELEPORT) == SETPOS_OK) { script_pushint(st, true); } @@ -19836,15 +19842,14 @@ BUILDIN_FUNC(bg_join) { BUILDIN_FUNC(bg_team_setxy) { - struct battleground_data *bg; - int bg_id; + int bg_id = script_getnum(st,2); + std::shared_ptr bg = util::umap_find(bg_team_db, bg_id); - bg_id = script_getnum(st,2); - if( (bg = bg_team_search(bg_id)) == NULL ) - return SCRIPT_CMD_SUCCESS; + if (bg) { + bg->cemetery.x = script_getnum(st, 3); + bg->cemetery.y = script_getnum(st, 4); + } - bg->x = script_getnum(st,3); - bg->y = script_getnum(st,4); return SCRIPT_CMD_SUCCESS; } @@ -19903,10 +19908,15 @@ BUILDIN_FUNC(bg_monster_set_team) BUILDIN_FUNC(bg_leave) { struct map_session_data *sd = NULL; + bool deserter = false; + if( !script_charid2sd(2,sd) || !sd->bg_id ) return SCRIPT_CMD_SUCCESS; - bg_team_leave(sd,0); + if (!strcmp(script_getfuncname(st), "bg_desert")) + deserter = true; + + bg_team_leave(sd, false, deserter); return SCRIPT_CMD_SUCCESS; } @@ -19919,17 +19929,13 @@ BUILDIN_FUNC(bg_destroy) BUILDIN_FUNC(bg_getareausers) { - const char *str; + const char *str = script_getstr(st, 3); int16 m, x0, y0, x1, y1; - int bg_id; + int bg_id = script_getnum(st, 2); int i = 0, c = 0; - struct battleground_data *bg = NULL; + std::shared_ptr bg = util::umap_find(bg_team_db, bg_id); - bg_id = script_getnum(st,2); - str = script_getstr(st,3); - - if( (bg = bg_team_search(bg_id)) == NULL || (m = map_mapname2mapid(str)) < 0 ) - { + if (!bg || (m = map_mapname2mapid(str)) < 0) { script_pushint(st,0); return SCRIPT_CMD_SUCCESS; } @@ -19939,7 +19945,7 @@ BUILDIN_FUNC(bg_getareausers) x1 = script_getnum(st,6); y1 = script_getnum(st,7); - for( i = 0; i < MAX_BG_MEMBERS; i++ ) + for( i = 0; i < bg->members.size(); i++ ) { struct map_session_data *sd; if( (sd = bg->members[i].sd) == NULL ) @@ -19973,29 +19979,102 @@ BUILDIN_FUNC(bg_updatescore) BUILDIN_FUNC(bg_get_data) { - struct battleground_data *bg = bg_team_search( script_getnum(st, 2) ); + int bg_id = script_getnum(st,2), type = script_getnum(st,3), i; + std::shared_ptr bg = util::umap_find(bg_team_db, bg_id); - if (bg == NULL) { - script_pushint(st, 0); - return SCRIPT_CMD_SUCCESS; - } - int i, j, type = script_getnum(st, 3); - - switch( type ) { - case 0: - script_pushint(st, bg->count); - break; - case 1: - for (i = 0, j = 0; i < ARRAYLENGTH(bg->members); i++) { - if (bg->members[i].sd != NULL) - mapreg_setreg(reference_uid(add_str("$@arenamembers"), j++), bg->members[i].sd->bl.id); + if (bg) { + switch (type) { + case 0: + script_pushint(st, bg->members.size()); + break; + case 1: + for (i = 0; bg->members[i].sd != NULL; i++) + mapreg_setreg(reference_uid(add_str("$@arenamembers"), i), bg->members[i].sd->bl.id); + mapreg_setreg(add_str("$@arenamemberscount"), i); + script_pushint(st, i); + break; + default: + ShowError("script:bg_get_data: unknown data identifier %d\n", type); + break; } - mapreg_setreg(add_str("$@arenamemberscount"), j); - script_pushint(st, j); - break; - default: - ShowError("script:bg_get_data: unknown data identifier %d\n", type); - break; + } else + script_pushint(st, 0); + + return SCRIPT_CMD_SUCCESS; +} + +/** + * Reserves a slot for the given Battleground. + * bg_reserve(<"bg_name">); + */ +BUILDIN_FUNC(bg_reserve) +{ + const char *str = script_getstr(st, 2); + + if (!bg_queue_reserve(str)) + ShowWarning("buildin_bg_reserve: Could not reserve battleground with name %s\n", str); + return SCRIPT_CMD_SUCCESS; +} + +/** + * Removes a spot for the given Battleground. + * bg_unbook(<"bg_name">); + */ +BUILDIN_FUNC(bg_unbook) +{ + const char *str = script_getstr(st, 2); + + if (!bg_queue_unbook(str)) + ShowWarning("buildin_bg_unbook: Could not unreserve battleground with name %s\n", str); + return SCRIPT_CMD_SUCCESS; +} + +/** + * Gets battleground database information. + * bg_info("", ); + */ +BUILDIN_FUNC(bg_info) +{ + std::shared_ptr bg = bg_search_name(script_getstr(st, 2)); + + if (!bg) { + ShowError("bg_info: Invalid Battleground name %s.\n", script_getstr(st, 2)); + return SCRIPT_CMD_FAILURE; + } + + int type = script_getnum(st, 3); + + switch (type) { + case BG_INFO_ID: + script_pushint(st, bg->id); + break; + case BG_INFO_REQUIRED_PLAYERS: + script_pushint(st, bg->required_players); + break; + case BG_INFO_MAX_PLAYERS: + script_pushint(st, bg->max_players); + break; + case BG_INFO_MIN_LEVEL: + script_pushint(st, bg->min_lvl); + break; + case BG_INFO_MAX_LEVEL: + script_pushint(st, bg->max_lvl); + break; + case BG_INFO_MAPS: { + size_t i; + + for (i = 0; i < bg->maps.size(); i++) + setd_sub_str(st, nullptr, ".@bgmaps$", i, map_mapid2mapname(bg->maps[i].mapid), nullptr); + setd_sub_num(st, nullptr, ".@bgmapscount", 0, i, nullptr); + script_pushint(st, i); + break; + } + case BG_INFO_DESERTER_TIME: + script_pushint(st, bg->deserter_time); + break; + default: + ShowError("bg_info: Unknown battleground info type %d given.\n", type); + return SCRIPT_CMD_FAILURE; } return SCRIPT_CMD_SUCCESS; @@ -25028,6 +25107,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(bg_monster,"isiisi?"), BUILDIN_DEF(bg_monster_set_team,"ii"), BUILDIN_DEF(bg_leave,"?"), + BUILDIN_DEF2(bg_leave,"bg_desert","?"), BUILDIN_DEF(bg_destroy,"i"), BUILDIN_DEF(areapercentheal,"siiiiii"), BUILDIN_DEF(bg_get_data,"ii"), @@ -25035,6 +25115,9 @@ struct script_function buildin_func[] = { BUILDIN_DEF(bg_updatescore,"sii"), BUILDIN_DEF(bg_join,"i????"), BUILDIN_DEF(bg_create,"sii??"), + BUILDIN_DEF(bg_reserve,"s"), + BUILDIN_DEF(bg_unbook,"s"), + BUILDIN_DEF(bg_info,"si"), // Instancing BUILDIN_DEF(instance_create,"s??"), diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index db9f419645..f23a1fb196 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -1542,6 +1542,8 @@ export_constant(SC_ANCILLA); export_constant(SC_EARTHSHAKER); export_constant(SC_WEAPONBLOCK_ON); + export_constant(SC_ENTRY_QUEUE_APPLY_DELAY); + export_constant(SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT); #ifdef RENEWAL export_constant(SC_EXTREMITYFIST2); #endif @@ -7689,6 +7691,15 @@ export_constant(UNT_GD_SOULCOLD); export_constant(UNT_GD_HAWKEYES); + /* battleground info types */ + export_constant(BG_INFO_ID); + export_constant(BG_INFO_REQUIRED_PLAYERS); + export_constant(BG_INFO_MAX_PLAYERS); + export_constant(BG_INFO_MIN_LEVEL); + export_constant(BG_INFO_MAX_LEVEL); + export_constant(BG_INFO_MAPS); + export_constant(BG_INFO_DESERTER_TIME); + #undef export_constant #undef export_constant2 #undef export_parameter diff --git a/src/map/skill.cpp b/src/map/skill.cpp index ffc1548261..46cc06826e 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -2027,6 +2027,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 case SC_WEDDING: case SC_XMAS: case SC_SUMMER: case SC_DRESSUP: case SC_HANBOK: case SC_OKTOBERFEST: case SC_LHZ_DUN_N1: case SC_LHZ_DUN_N2: case SC_LHZ_DUN_N3: case SC_LHZ_DUN_N4: + case SC_ENTRY_QUEUE_APPLY_DELAY: case SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT: continue; case SC_WHISTLE: case SC_ASSNCROS: case SC_POEMBRAGI: case SC_APPLEIDUN: case SC_HUMMING: case SC_DONTFORGETME: @@ -7997,6 +7998,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SC_SPRITEMABLE: case SC_BITESCAR: case SC_CRUSHSTRIKE: case SC_QUEST_BUFF1: case SC_QUEST_BUFF2: case SC_QUEST_BUFF3: case SC_ARMOR_ELEMENT_EARTH: case SC_ARMOR_ELEMENT_FIRE: case SC_ARMOR_ELEMENT_WIND: + case SC_ENTRY_QUEUE_APPLY_DELAY: case SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT: // Clans case SC_CLAN_INFO: case SC_SWORDCLAN: @@ -9455,6 +9457,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SC_WEDDING: case SC_XMAS: case SC_SUMMER: case SC_DRESSUP: case SC_HANBOK: case SC_OKTOBERFEST: case SC_LHZ_DUN_N1: case SC_LHZ_DUN_N2: case SC_LHZ_DUN_N3: case SC_LHZ_DUN_N4: + case SC_ENTRY_QUEUE_APPLY_DELAY: case SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT: continue; case SC_ASSUMPTIO: if( bl->type == BL_MOB ) diff --git a/src/map/status.cpp b/src/map/status.cpp index 56235cde1b..f6a365bbf9 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -17,6 +17,7 @@ #include "../common/showmsg.hpp" #include "../common/strlib.hpp" #include "../common/timer.hpp" +#include "../common/utilities.hpp" #include "../common/utils.hpp" #include "battle.hpp" @@ -36,6 +37,8 @@ #include "pet.hpp" #include "script.hpp" +using namespace rathena; + // Regen related flags. enum e_regen { RGN_NONE = 0x00, @@ -1179,6 +1182,10 @@ void initChangeTables(void) StatusIconChangeTable[SC_ANCILLA] = EFST_ANCILLA; StatusIconChangeTable[SC_WEAPONBLOCK_ON] = EFST_WEAPONBLOCK_ON; + // Battleground Queue + StatusIconChangeTable[SC_ENTRY_QUEUE_APPLY_DELAY] = EFST_ENTRY_QUEUE_APPLY_DELAY; + StatusIconChangeTable[SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT] = EFST_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT; + /* Other SC which are not necessarily associated to skills */ StatusChangeFlagTable[SC_ASPDPOTION0] |= SCB_ASPD; StatusChangeFlagTable[SC_ASPDPOTION1] |= SCB_ASPD; @@ -1333,6 +1340,10 @@ void initChangeTables(void) StatusChangeFlagTable[SC_GLASTHEIM_ITEMDEF] |= SCB_DEF|SCB_MDEF; StatusChangeFlagTable[SC_GLASTHEIM_HPSP] |= SCB_MAXHP|SCB_MAXSP; + // Battleground Queue + StatusChangeFlagTable[SC_ENTRY_QUEUE_APPLY_DELAY] |= SCB_NONE; + StatusChangeFlagTable[SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT] |= SCB_NONE; + // Summoner StatusChangeFlagTable[SC_DORAM_WALKSPEED] |= SCB_SPEED; StatusChangeFlagTable[SC_DORAM_MATK] |= SCB_MATK; @@ -1864,14 +1875,15 @@ int status_damage(struct block_list *src,struct block_list *target,int64 dhp, in } // Always run NPC scripts for players last - //FIXME those ain't always run if a player die if he was resurect meanwhile + //FIXME those ain't always run if a player die if he was resurrect meanwhile //cf SC_REBIRTH, SC_KAIZEL, pc_dead... if(target->type == BL_PC) { TBL_PC *sd = BL_CAST(BL_PC,target); if( sd->bg_id ) { - struct battleground_data *bg; - if( (bg = bg_team_search(sd->bg_id)) != NULL && bg->die_event[0] ) - npc_event(sd, bg->die_event, 0); + std::shared_ptr bg = util::umap_find(bg_team_db, sd->bg_id); + + if( bg && !(bg->die_event.empty()) ) + npc_event(sd, bg->die_event.c_str(), 0); } npc_script_event(sd,NPCE_DIE); @@ -12016,6 +12028,8 @@ int status_change_clear(struct block_list* bl, int type) case SC_LHZ_DUN_N2: case SC_LHZ_DUN_N3: case SC_LHZ_DUN_N4: + case SC_ENTRY_QUEUE_APPLY_DELAY: + case SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT: // Costumes case SC_MOONSTAR: case SC_SUPER_STAR: @@ -12050,6 +12064,8 @@ int status_change_clear(struct block_list* bl, int type) case SC_PUSH_CART: case SC_ALL_RIDING: case SC_STYLE_CHANGE: + case SC_ENTRY_QUEUE_APPLY_DELAY: + case SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT: // Costumes case SC_MOONSTAR: case SC_SUPER_STAR: diff --git a/src/map/status.hpp b/src/map/status.hpp index 6bfdcd767a..c9aa405624 100644 --- a/src/map/status.hpp +++ b/src/map/status.hpp @@ -864,6 +864,9 @@ enum sc_type : int16 { SC_WEAPONBLOCK_ON, SC_SPORE_EXPLOSION, + SC_ENTRY_QUEUE_APPLY_DELAY, + SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT, + #ifdef RENEWAL SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled #endif diff --git a/tools/ci/npc.bat b/tools/ci/npc.bat index 5e0b611e80..7bef87de64 100644 --- a/tools/ci/npc.bat +++ b/tools/ci/npc.bat @@ -26,11 +26,8 @@ for /R . %%f in (*.txt) do ( set B=%%f rem store relative path for compare set R=!B:%C%\=! - - rem all except the battleground scripts - if "!R:~0,12!" neq "battleground" ( - echo npc: npc\custom\!R!>>!OUT! - ) + + echo npc: npc\custom\!R!>>!OUT! ) rem switch to the test folder diff --git a/tools/ci/npc.sh b/tools/ci/npc.sh index 22f7f83bdd..98fb6f4f88 100755 --- a/tools/ci/npc.sh +++ b/tools/ci/npc.sh @@ -5,7 +5,7 @@ out=npc/scripts_custom.conf printf "\n" >> $out echo "// Custom Scripts" >> $out -find npc/custom \( -name "*.txt" -and -not -wholename "*/battleground/*" \) | xargs -I % echo "npc: %" >> $out +find npc/custom \( -name "*.txt" \) | xargs -I % echo "npc: %" >> $out echo "// Test Scripts" >> $out