Aegis Support Board: WoE castle rotation - Aegis Support Board

Jump to content

ASB News! ASB 5.0 Beta V2 has now been released!. See here for more Info.

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

WoE castle rotation

#1 User is offline   Kasuha 

  • Average Member
  • PipPipPipPip
  • Group: Members
  • Posts: 195
  • Joined: 08-February 05

Posted 09 October 2006 - 07:58 AM

This script might be useful for servers with less players which don't have all castles open, yet they want to allow players to eventually reach all castles. As far as I know, a similar thing is used on oRO, though they use the way of removing the whole WoE scripts from server instead of closing/opening individual castles.
This script doesn't need a server restart to switch castles and it doesn't need any GM attention except for initial setup. The switch is done at midnight time, the period (in days) can be changed by changing the script. All castles remain to their respective owners, only the closed castles are completely inaccessible until they are open again.

This particular script has eight castles open (two in each town) and "rotates" them in five phases once every month (the full circle is done in five months).

The following global variables are used by this script:

Rotate.WatchTime ... is updated sometimes by the current time to overcome server downtimes.
Rotate.Month ... contains the number of the current month
Rotate.DaysLeft ... contains the number of days left to the next rotation. When rotation occurs, it is updated to the new value based on the current month
Rotate.Phase ... the current phase of castle rotation
Rotate.<castle> (e.g. Rotate.aldeg_cas01) ... the status of a castle. 0 means closed castle, 1 means open castle

When setting things up, you should set:
Rotate.WatchTime to 0
Rotate.Month to the current month
Rotate.DaysLeft to the number of days till the next rotation. 1 means this midnight.
Rotate.Phase preferably to 1 but you can choose any phase
Rotate.<castle>s to the current status

The main NPC checks and broadcasts WoE time and also checks and performs the castle rotation:

npc "prtg_cas01" "GW Watcher" HIDDEN_NPC 2 2 0 0 0
// initialization - get the time of last check before shutdown
OnInit:
	strlocalvar 0 "GWstatus"
	SetLocalVar "GWstatus" 0
	strlocalvar 1 "LastTime"
	SetLocalVar "LastTime" (GetGlobalVar "Rotate.WatchTime")
	strlocalvar 2 "SaveTime"
	SetLocalVar "SaveTime" lv["LastTime"]
	cmdothernpc "GW Watcher" "Run"
	return

// date has changed
// determine if the castle rotation should occur. If yes, set the number of days to the next rotation
// based on the current month
OnCommand: "DateChange"
	var daysleft = GetGlobalVar "Rotate.DaysLeft"
	daysleft = daysleft - 1
	if daysleft < 1
		cmdothernpc "GW Watcher" "Rotate"
		var month = GetGlobalVar "Rotate.Month"
		month = month + 1
		if month > 12
			month = 1
		endif
		if (month == 1) | (month == 3) | (month == 5) | (month == 7) | (month == 8) | (month == 10) | (month == 12)
			daysleft = 31
		elseif (month == 2)
			daysleft = 28
		else
			daysleft = 30
		endif
		SetGlobalVar "Rotate.Month" month
	endif
	SetGlobalVar "Rotate.DaysLeft" daysleft
	return

// castle rotation occured - get the number of the current phase
// and set all for the next phase
// by setting castle variables appropriately
OnCommand: "Rotate"
	var phase = GetGlobalVar "Rotate.Phase"
	choose phase
	case 1
		phase = 2
		SetGlobalVar "Rotate.aldeg_cas01" 0
		SetGlobalVar "Rotate.aldeg_cas02" 1
		SetGlobalVar "Rotate.aldeg_cas03" 1
		SetGlobalVar "Rotate.aldeg_cas04" 0
		SetGlobalVar "Rotate.aldeg_cas05" 0

		SetGlobalVar "Rotate.gefg_cas01" 0
		SetGlobalVar "Rotate.gefg_cas02" 1
		SetGlobalVar "Rotate.gefg_cas03" 1
		SetGlobalVar "Rotate.gefg_cas04" 0
		SetGlobalVar "Rotate.gefg_cas05" 0

		SetGlobalVar "Rotate.payg_cas01" 0
		SetGlobalVar "Rotate.payg_cas02" 0
		SetGlobalVar "Rotate.payg_cas03" 1
		SetGlobalVar "Rotate.payg_cas04" 1
		SetGlobalVar "Rotate.payg_cas05" 0

		SetGlobalVar "Rotate.prtg_cas01" 0
		SetGlobalVar "Rotate.prtg_cas02" 1
		SetGlobalVar "Rotate.prtg_cas03" 0
		SetGlobalVar "Rotate.prtg_cas04" 1
		SetGlobalVar "Rotate.prtg_cas05" 0
		break
	case 2
		phase = 3
		SetGlobalVar "Rotate.aldeg_cas01" 0
		SetGlobalVar "Rotate.aldeg_cas02" 0
		SetGlobalVar "Rotate.aldeg_cas03" 1
		SetGlobalVar "Rotate.aldeg_cas04" 1
		SetGlobalVar "Rotate.aldeg_cas05" 0

		SetGlobalVar "Rotate.gefg_cas01" 0
		SetGlobalVar "Rotate.gefg_cas02" 0
		SetGlobalVar "Rotate.gefg_cas03" 1
		SetGlobalVar "Rotate.gefg_cas04" 0
		SetGlobalVar "Rotate.gefg_cas05" 1

		SetGlobalVar "Rotate.payg_cas01" 1
		SetGlobalVar "Rotate.payg_cas02" 0
		SetGlobalVar "Rotate.payg_cas03" 1
		SetGlobalVar "Rotate.payg_cas04" 0
		SetGlobalVar "Rotate.payg_cas05" 0

		SetGlobalVar "Rotate.prtg_cas01" 0
		SetGlobalVar "Rotate.prtg_cas02" 0
		SetGlobalVar "Rotate.prtg_cas03" 1
		SetGlobalVar "Rotate.prtg_cas04" 1
		SetGlobalVar "Rotate.prtg_cas05" 0
		break
	case 3
		phase = 4
		SetGlobalVar "Rotate.aldeg_cas01" 0
		SetGlobalVar "Rotate.aldeg_cas02" 0
		SetGlobalVar "Rotate.aldeg_cas03" 0
		SetGlobalVar "Rotate.aldeg_cas04" 1
		SetGlobalVar "Rotate.aldeg_cas05" 1

		SetGlobalVar "Rotate.gefg_cas01" 0
		SetGlobalVar "Rotate.gefg_cas02" 0
		SetGlobalVar "Rotate.gefg_cas03" 0
		SetGlobalVar "Rotate.gefg_cas04" 1
		SetGlobalVar "Rotate.gefg_cas05" 1

		SetGlobalVar "Rotate.payg_cas01" 1
		SetGlobalVar "Rotate.payg_cas02" 1
		SetGlobalVar "Rotate.payg_cas03" 0
		SetGlobalVar "Rotate.payg_cas04" 0
		SetGlobalVar "Rotate.payg_cas05" 0

		SetGlobalVar "Rotate.prtg_cas01" 0
		SetGlobalVar "Rotate.prtg_cas02" 0
		SetGlobalVar "Rotate.prtg_cas03" 1
		SetGlobalVar "Rotate.prtg_cas04" 0
		SetGlobalVar "Rotate.prtg_cas05" 1
		break
	case 4
		phase = 5
		SetGlobalVar "Rotate.aldeg_cas01" 1
		SetGlobalVar "Rotate.aldeg_cas02" 0
		SetGlobalVar "Rotate.aldeg_cas03" 0
		SetGlobalVar "Rotate.aldeg_cas04" 0
		SetGlobalVar "Rotate.aldeg_cas05" 1

		SetGlobalVar "Rotate.gefg_cas01" 1
		SetGlobalVar "Rotate.gefg_cas02" 0
		SetGlobalVar "Rotate.gefg_cas03" 0
		SetGlobalVar "Rotate.gefg_cas04" 1
		SetGlobalVar "Rotate.gefg_cas05" 0

		SetGlobalVar "Rotate.payg_cas01" 0
		SetGlobalVar "Rotate.payg_cas02" 1
		SetGlobalVar "Rotate.payg_cas03" 0
		SetGlobalVar "Rotate.payg_cas04" 0
		SetGlobalVar "Rotate.payg_cas05" 1

		SetGlobalVar "Rotate.prtg_cas01" 1
		SetGlobalVar "Rotate.prtg_cas02" 0
		SetGlobalVar "Rotate.prtg_cas03" 0
		SetGlobalVar "Rotate.prtg_cas04" 0
		SetGlobalVar "Rotate.prtg_cas05" 1
		break
	case 5
		phase = 1
		SetGlobalVar "Rotate.aldeg_cas01" 1
		SetGlobalVar "Rotate.aldeg_cas02" 1
		SetGlobalVar "Rotate.aldeg_cas03" 0
		SetGlobalVar "Rotate.aldeg_cas04" 0
		SetGlobalVar "Rotate.aldeg_cas05" 0

		SetGlobalVar "Rotate.gefg_cas01" 1
		SetGlobalVar "Rotate.gefg_cas02" 1
		SetGlobalVar "Rotate.gefg_cas03" 0
		SetGlobalVar "Rotate.gefg_cas04" 0
		SetGlobalVar "Rotate.gefg_cas05" 0

		SetGlobalVar "Rotate.payg_cas01" 0
		SetGlobalVar "Rotate.payg_cas02" 0
		SetGlobalVar "Rotate.payg_cas03" 0
		SetGlobalVar "Rotate.payg_cas04" 1
		SetGlobalVar "Rotate.payg_cas05" 1

		SetGlobalVar "Rotate.prtg_cas01" 1
		SetGlobalVar "Rotate.prtg_cas02" 1
		SetGlobalVar "Rotate.prtg_cas03" 0
		SetGlobalVar "Rotate.prtg_cas04" 0
		SetGlobalVar "Rotate.prtg_cas05" 0
		break
	endchoose
	SetGlobalVar "Rotate.Phase" phase
	
	cmdothernpc "aldeg_cas01_control" "refresh"
	cmdothernpc "aldeg_cas02_control" "refresh"
	cmdothernpc "aldeg_cas03_control" "refresh"
	cmdothernpc "aldeg_cas04_control" "refresh"
	cmdothernpc "aldeg_cas05_control" "refresh"

	cmdothernpc "gefg_cas01_control" "refresh"
	cmdothernpc "gefg_cas02_control" "refresh"
	cmdothernpc "gefg_cas03_control" "refresh"
	cmdothernpc "gefg_cas04_control" "refresh"
	cmdothernpc "gefg_cas05_control" "refresh"

	cmdothernpc "payg_cas01_control" "refresh"
	cmdothernpc "payg_cas02_control" "refresh"
	cmdothernpc "payg_cas03_control" "refresh"
	cmdothernpc "payg_cas04_control" "refresh"
	cmdothernpc "payg_cas05_control" "refresh"

	cmdothernpc "prtg_cas01_control" "refresh"
	cmdothernpc "prtg_cas02_control" "refresh"
	cmdothernpc "prtg_cas03_control" "refresh"
	cmdothernpc "prtg_cas04_control" "refresh"
	cmdothernpc "prtg_cas05_control" "refresh"

	broadcastserver "FF0000" FW_NORMAL 10 0 0 "Guild castles have been rotated."

	return
	
// init timer to repeat the check
OnCommand: "Run"
	InitTimer
	return
	
// check the time and also check if it is WoE time
OnTimer: 1000
	var stime = ServerTime
	if stime < lv["LastTime"]
		cmdothernpc "GW Watcher" "DateChange"
		SetLocalVar "SaveTime" (stime + 1000)
		SetGlobalVar "Rotate.WatchTime" stime
	elseif stime >= lv["SaveTime"]
		SetLocalVar "SaveTime" (stime + 1000)
		SetGlobalVar "Rotate.WatchTime" stime
	endif
	SetLocalVar "LastTime" stime
	var empvisible = AgitNpcGet AGIT_NPC_EMPELIUM AN_VISIBLE
	if empvisible == 1
		if lv["GWstatus"] == 0
			broadcastserver "00FF00" FW_NORMAL 10 0 0 "WoE started"
		endif
		SetLocalVar "GWstatus" 5
	else
		if lv["GWstatus"] > 0
			SetLocalVar "GWstatus" (lv["GWstatus"] - 1)
			if lv["GWstatus"] == 0
				broadcastserver "00FF00" FW_NORMAL 10 0 0 "WoE ended"
			endif
		endif
	endif
	cmdothernpc "GW Watcher" "Run"
	stoptimer
	return


The next NPC is one per each castle. It takes care of the castle being open/closed on server start and also on the status change. When the castle is being closed, it takes care of removing all characters that are inside. They are warped to the town mutliple times to avoid the warp bug.

npc "aldeg_cas01" "aldeg_cas01_control" HIDDEN_NPC 1 1 0 0 0
OnInit:
	strlocalvar 0 "PrevStatus"
	SetLocalVar "PrevStatus" 1
	cmdothernpc "aldeg_cas01_control" "refresh"
	return
OnCommand: "refresh"
	var newStatus = GetGlobalVar "Rotate.aldeg_cas01"
	if newStatus != lv["PrevStatus"]
		SetLocalVar "PrevStatus" newStatus
		if newStatus == 1
			cmdothernpc "aldeg_cas01_entry" "on"
		else
			cmdothernpc "aldeg_cas01_entry" "off"
			InitTimer
		endif
	endif
	return
OnTimer: 100
	warpallpcinthemap "aldebaran" 143 112
	return
OnTimer: 1000
	warpallpcinthemap "aldebaran" 143 112
	return
OnTimer: 2000
	warpallpcinthemap "aldebaran" 143 112
	return
OnTimer: 3000
	warpallpcinthemap "aldebaran" 143 112
	return
OnTimer: 4000
	warpallpcinthemap "aldebaran" 143 112
	return
OnTimer: 5000
	warpallpcinthemap "aldebaran" 143 112
	return
OnTimer: 6000
	warpallpcinthemap "aldebaran" 143 112
	return
OnTimer: 7000
	warpallpcinthemap "aldebaran" 143 112
	return
OnTimer: 8000
	warpallpcinthemap "aldebaran" 143 112
	return
OnTimer: 9000
	warpallpcinthemap "aldebaran" 143 112
	return
OnTimer: 10000
	warpallpcinthemap "aldebaran" 143 112
	stoptimer
	return


All warps leading into the castle must be enabled/disabled according to the current castle status. Note that they don't need to care about it during startup, as the castle control NPC above cares about it.
Just don't forget that some of Geffen castles have more than one entrance.

warp "alde_gld" "aldeg_cas01_entry" 48 77 5 2
OnCommand: "on"
	enablenpc "aldeg_cas01_entry"
	return
OnCommand: "off"
	disablenpc "aldeg_cas01_entry"
	return
OnTouch:
	moveto "aldeg_cas01" 34 248
	return


All the flags that warp owner guild members into the castle must also take care of the castle status. Note that the check is done two times.

npc "alde_gld" "Neuschwanstein" GUILD_FLAG 61 87 6 0 0
	...
		var active = GetGlobalVar "Rotate.aldeg_cas01"
		if (guildID == v[VAR_GDID]) & (active != 0)
			dialog "[ Vibration of Man's Voice ]"
			dialog "The brave soldiers..."
			dialog "Would you like to go back?"
			wait
			choose menu "Go back to guild base." "Cancel."
			case 1
				guildID  = AgitGet2 "aldeg_cas01" AGIT_GUILD
				active = GetGlobalVar "Rotate.aldeg_cas01"
				if (guildID == v[VAR_GDID]) & (active != 0)
					moveto "aldeg_cas01" 218 170
				endif
				return
			case 2
				break
			endchoose
		endif
	...


And for the security measures, the castle NPCs should be also checking if the castle is open to disallow increasing castle invests etc when the castle is closed. This check could be done:
- for guardian installation
- for economy investment
- for defense investment
- for treasure room entry
- for Kafra installation
- for Guild Dungeon entry

	...
			if (GetGlobalVar "Rotate.aldeg_cas01") == 0
				dialog "- this castle is closed -"
				close
				return
			endif

			dropgold gold
			AgitFunc AF_INVEST_E 0 0

			dialog "[Arl Fredo]"
			dialog "You invested successfully."
			return
	...


The full script is a little too long and I don't think it's necessary to post it here as I hope that you can edit your WoE scripts using these guidelines rather easily.

This post has been edited by Kasuha: 09 October 2006 - 03:36 PM

0

#2 User is offline   980542 

  • Average Member
  • PipPipPipPip
  • Group: Members
  • Posts: 106
  • Joined: 21-December 05

Posted 12 October 2006 - 08:36 AM

Awesome work, thx ^_^

I was going the other way around. Like cloning guild maps so i could use npcs to call random treasure boxes and sending players to these new maps treasure rooms to get them instead of the real ones.

Btw, I dont know for how long have you been testing the GW Watcher npc idea. For me, it didnt work that well. After some days, it lost the correct day i believe by some delay after counting the time needed to command other npcs and to actually command them... I end up asking another GM to make another way to count days (like php or somehting else wich i dont know) and storing that data into the globalvar. Worked pretty good.
0

#3 User is offline   Kasuha 

  • Average Member
  • PipPipPipPip
  • Group: Members
  • Posts: 195
  • Joined: 08-February 05

Posted 13 October 2006 - 05:11 PM

There is one pretty easy way how to get current date by hooking up the GetGlobalVar stored procedure. I have posted an example how to do that here and it can be used to get the current date the same way as long as you know the correct SQL command to get current date.

The watcher should not fall out of sync if the server is not stopped for a period over 24 hours and if no rollbacks occur. As long as we didn't have severe downtimes lately I didn't find it necessary to hook up globvars to get the date.
0

#4 User is offline   Kasuha 

  • Average Member
  • PipPipPipPip
  • Group: Members
  • Posts: 195
  • Joined: 08-February 05

Posted 17 October 2006 - 05:11 PM

Oh, now I noticed the problem... if you have an automatic time correction on your server, the server time may change randomly forward or back depending on the quality of your server's internal clock. This may confuse the date change detection in the script. That way it might really lose sync even though you don't have rollbacks or downtimes. A fix is to put some tolerance to the check - for instance this value will create a tolerance up to one hour:

...
OnTimer: 1000
	var stime = ServerTime
	if (stime + 10000) < lv["LastTime"]
		...

This post has been edited by Kasuha: 17 October 2006 - 05:11 PM

0

#5 User is offline   980542 

  • Average Member
  • PipPipPipPip
  • Group: Members
  • Posts: 106
  • Joined: 21-December 05

Posted 15 November 2006 - 06:39 PM

warp "alde_gld" "aldeg_cas01_entry" 48 77 5 2
OnCommand: "on"
	enablenpc "aldeg_cas01_entry"
	return
OnCommand: "off"
	disablenpc "aldeg_cas01_entry"
	return
OnTouch:
	moveto "aldeg_cas01" 34 248
	return


Did you try use the control npc to disable and enable the warps instead of commanding them to disable and enable themselves?
I ask cause it would be less stuff to do and more practical if it works.

This post has been edited by 980542: 15 November 2006 - 06:43 PM

0

#6 User is offline   Kasuha 

  • Average Member
  • PipPipPipPip
  • Group: Members
  • Posts: 195
  • Joined: 08-February 05

Posted 16 November 2006 - 02:03 PM

View Post980542, on Nov 16 2006, 02:39 AM, said:

warp "alde_gld" "aldeg_cas01_entry" 48 77 5 2
OnCommand: "on"
	enablenpc "aldeg_cas01_entry"
	return
OnCommand: "off"
	disablenpc "aldeg_cas01_entry"
	return
OnTouch:
	moveto "aldeg_cas01" 34 248
	return


Did you try use the control npc to disable and enable the warps instead of commanding them to disable and enable themselves?
I ask cause it would be less stuff to do and more practical if it works.

In official scripts this is always done this way, I think it might be because cmdothernpc can pass between different Zone servers while dis/enablenpc can't but I'm not sure about it (having just one zone, nowhere to test it).
Apart from that, it sure works.
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users