Merge lp:~armagetronad-ct/armagetronad/0.4-delaycmd into lp:~armagetronad-dev/armagetronad/0.4-armagetronad-work

Proposed by Voodoo
Status: Needs review
Proposed branch: lp:~armagetronad-ct/armagetronad/0.4-delaycmd
Merge into: lp:~armagetronad-dev/armagetronad/0.4-armagetronad-work
Diff against target: 115 lines (+91/-0)
1 file modified
src/tron/gGame.cpp (+91/-0)
To merge this branch: bzr merge lp:~armagetronad-ct/armagetronad/0.4-delaycmd
Reviewer Review Type Date Requested Status
Armagetron Advanced Developers Pending
Review via email: mp+130693@code.launchpad.net

Description of the change

Hey,

I don't know if it worth including it in mainstream but it happens to be a useful feature for servers like ed's onslaught fortress, mayhem or flower power, and it was just a matter of a few minutes to extract it.
This is the delay_command from sty+ct rewritten a while ago for my experiments on scripting (armagetronad-ct branch). It works the exact same way as in sty+ct:
delay_command [r<repeat_delay>] [+-]<start_delay> <command>

The optional + indicates whether start_delay is relative instead of absolute.
The optional - indicates it should be send before game start (absolute time during countdown)
The repeat option was added by kyle later (may be for some wild fortress maps) and is rather self explanatory.

I allows to avoid external scripting in simple cases like timing messages and scoring (onslaught) or sending stages settings (mayhem).

Some typical example:
delay_command 60 center_message 2 minutes left!

delay_command 37 center_message - 3 -
delay_command 38 center_message - 2 -
delay_command 39 center_message - 1 -
delay_command 40 center_message Stage 2 is starting now!
delay_command 40 cycle_speed 50
...

To post a comment you must log in.

Unmerged revisions

1454. By Voodoo

add delay_command to 0.4

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/tron/gGame.cpp'
2--- src/tron/gGame.cpp 2012-08-26 15:53:43 +0000
3+++ src/tron/gGame.cpp 2012-10-21 07:50:24 +0000
4@@ -759,6 +759,93 @@
5 static tSettingItem<bool> sg_ttm("TALK_TO_MASTER",
6 sg_TalkToMaster);
7
8+// *************************
9+// *** delayed commands
10+// *************************
11+
12+class delayedCommands {
13+private:
14+ static std::map<int, std::set<std::string> > cmd_map;
15+ // compute key for std::multimap
16+ static int Key(REAL time) {return int(ceil(time*10));};
17+public:
18+ // clear all delayed commands
19+ static void Clear() {
20+ cmd_map.clear();
21+ con << "Clearing delayed commands ...\n";
22+ };
23+ // add new delayed commands
24+ static void Add(REAL time, std::string cmd, int interval) {
25+ std::stringstream store;
26+ store << interval << " " << cmd;
27+ cmd_map[Key(time)].insert(store.str());
28+ };
29+ // check, run and remove delayed commands
30+ static void Run(REAL currentTime);
31+};
32+
33+std::map<int, std::set<std::string> > delayedCommands::cmd_map;
34+
35+static void sg_AddDelayedCmd(std::istream &s)
36+{
37+ // first parse the line to get the param : delay or interval
38+ // if the param start by an r then it means we have the interval
39+ // if the param start by a +, assume that it's a delay relative to current game time ...
40+ int interval=0;
41+ tString delay_str;
42+ s >> delay_str;
43+ if (delay_str.SubStr(0,1)=="r") {
44+ interval = atoi(delay_str.SubStr(1));
45+ s >> delay_str;
46+ }
47+ REAL delay = atof(delay_str);
48+ if (delay_str.SubStr(0,1)=="+") {
49+ REAL gt = se_GameTime();
50+ delay += gt;
51+ }
52+ // this will make sure it using the command if start time has passed
53+ if ((interval > 0) && (se_GameTime() > delay)){
54+ REAL ogt = se_GameTime() - delay;
55+ int disposition = (ogt/interval)+1;
56+ delay = disposition*interval+delay;
57+ }
58+ tString cmd_str;
59+ cmd_str.ReadLine( s, true );
60+ if (cmd_str.length()==0) return;
61+
62+ // add extracted command
63+ delayedCommands::Add(delay,cmd_str,interval);
64+ //con << "DELAY_COMMAND " << delay << " "<< interval<<" &" << cmd_str.str() << "&\n";
65+}
66+
67+static tConfItemFunc sg_AddDelayedCmd_conf("DELAY_COMMAND",&sg_AddDelayedCmd);
68+static tAccessLevelSetter sg_AddDelayedCmdConfLevel( sg_AddDelayedCmd_conf, tAccessLevel_Owner );
69+
70+void delayedCommands::Run(REAL currentTime) {
71+ if (cmd_map.empty()) return;
72+ std::map<int, std::set<std::string> >::iterator it = cmd_map.begin();
73+ while ((it != cmd_map.end())&&(it->first<=Key(currentTime))) {
74+ if (it->first>Key(currentTime-1.0)) {
75+ std::set<std::string>::iterator sit (it->second.begin()), send(it->second.end());
76+ for(;sit!=send;++sit) {
77+ std::istringstream stream(*sit);
78+ int interval;
79+ stream >> interval;
80+ tCurrentAccessLevel elevator( sg_AddDelayedCmd_conf.GetRequiredLevel(), true );
81+ tConfItemBase::LoadAll(stream); // run command if it's not too old, otherwise, just skip it ...
82+ if (interval>0) {
83+ cmd_map[Key(currentTime+interval)].insert(stream.str());
84+ }
85+ }
86+ }
87+ cmd_map.erase(it++); // erase current and get next iterator
88+ }
89+}
90+
91+// *****************************
92+// *** end delayed commands
93+// *****************************
94+
95 #define PREPARE_TIME 4
96
97 static bool just_connected=true;
98@@ -3300,6 +3387,8 @@
99
100 Analysis(0);
101
102+ delayedCommands::Clear();
103+
104 // wait for external script to end its work if needed
105 REAL timeout = tSysTimeFloat() + sg_waitForExternalScriptTimeout;
106 if ( sg_waitForExternalScript )
107@@ -4604,6 +4693,8 @@
108 }
109 }
110
111+ delayedCommands::Run(gtime);
112+
113 static float lastTime = 1e42;
114
115 if(sg_gameTimeInterval >= 0 && (gtime >= lastTime + sg_gameTimeInterval || gtime < lastTime)) {

Subscribers

People subscribed via source and target branches