1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "client_cfg.h"
24 #include "init_main_loop.h"
25 #include "user_entity.h"
28 using namespace NLMISC
;
32 nlinfo("cbNotesChanged called");
35 CConfigFile::CVar
&var
= Notes
.NotesConfigFile
.getVar("Notes");
36 for(sint i
= 0; i
< var
.size(); i
+=3)
38 sint id
= var
.asInt(i
);
46 nlwarning("Malformated id 0 in note file '%s', discard all notes", ClientCfg
.NotesFilename
.c_str());
52 vector
<string
> posstr
;
53 explode(var
.asString(i
+1), ",", posstr
);
54 if(posstr
.size() != 3)
56 nlwarning("Malformated position in note number %d in file '%s', discard all notes", id
, ClientCfg
.NotesFilename
.c_str());
61 NLMISC::fromString(posstr
[0], pos
.x
);
62 NLMISC::fromString(posstr
[1], pos
.y
);
63 NLMISC::fromString(posstr
[2], pos
.z
);
65 string
note(var
.asString(i
+2));
68 nlwarning("Malformated because empty note in note number %d in file '%s', skipping it", id
, ClientCfg
.NotesFilename
.c_str());
72 Notes
.addNote(pos
, note
, id
);
77 C3DNotes::CNote::CNote(const NLMISC::CVector
&pos
, const std::string
¬e
, sint id
) :
78 Id(id
), Position(pos
), Note(note
), Bubble(NULL
)
83 C3DNotes::CNote::~CNote()
87 Bubble
->setActive(false);
95 if(!ClientCfg
.NotesFilename
.empty())
100 NotesConfigFile
.load(ClientCfg
.NotesFilename
);
101 NotesConfigFile
.setCallback(cbNotesChanged
);
102 NotesAvailable
= true;
107 nlwarning("Error while loading '%s': %s", ClientCfg
.NotesFilename
.c_str(), e
.what());
108 NotesAvailable
= false;
113 void C3DNotes::update()
115 if (!NotesAvailable
) return;
117 // check if we need new bubble
118 CVector userPos
= UserEntity
->pos();
119 for(list
<CNote
>::iterator it
= Notes
.begin(); it
!= Notes
.end(); it
++)
121 if((*it
).Bubble
== NULL
&& ((*it
).Position
- userPos
).norm() < 100)
123 string n
= toString("NOTE: %d %s", (*it
).Id
, (*it
).Note
.c_str());
124 (*it
).Bubble
= InSceneBubbleManager
.newBubble (ucstring(n
));
127 (*it
).Bubble
->link(NULL
, 60*60*10);
128 (*it
).Bubble
->setActive (true);
129 nlinfo("NOTE: id %d pos(%f,%f,%f) note '%s'", (*it
).Id
, (*it
).Position
.x
, (*it
).Position
.y
, (*it
).Position
.z
, (*it
).Note
.c_str());
132 else if((*it
).Bubble
&& ((*it
).Position
- userPos
).norm() >= 100)
134 (*it
).Bubble
->setActive(false);
135 (*it
).Bubble
->unlink();
141 (*it
).Bubble
->Position
= (*it
).Position
;
146 void C3DNotes::release()
151 void C3DNotes::saveNotes()
153 if (!NotesAvailable
) return;
157 vals
.push_back("0,0,0");
159 for(list
<CNote
>::iterator it
= Notes
.begin(); it
!= Notes
.end(); it
++)
161 vals
.push_back(toString("%d", (*it
).Id
));
162 vals
.push_back(toString("%f,%f,%f", (*it
).Position
.x
, (*it
).Position
.y
, (*it
).Position
.z
));
163 vals
.push_back((*it
).Note
);
166 CConfigFile::CVar
&var
= NotesConfigFile
.getVar("Notes");
167 var
.setAsString(vals
);
169 NotesConfigFile
.save();
172 void C3DNotes::addNote(const NLMISC::CVector
&pos
, const string
¬e
, sint id
)
174 if (!NotesAvailable
) return;
176 bool needToSave
= false;
183 Notes
.push_back(CNote(pos
, note
, id
));
194 void C3DNotes::removeNote(sint id
)
196 if (!NotesAvailable
) return;
198 for(list
<CNote
>::iterator it
= Notes
.begin(); it
!= Notes
.end(); it
++)
209 NLMISC_COMMAND(note
, "Add a 3d note at your location", "<note>")
222 string note
= toString("%s %s", un
, IDisplayer::dateToHumanString());
223 for (uint i
= 0; i
< args
.size(); i
++)
225 note
+= " " + args
[i
];
228 CVector pos
= UserEntity
->pos();
230 Notes
.addNote(pos
, note
);
235 NLMISC_COMMAND(removeNote
, "Remove a 3d note with its id", "<id>")
240 sint id
= atoi(args
[0].c_str());
243 log
.displayNL("0 is an invalid note id");
247 Notes
.removeNote(id
);
252 NLMISC_COMMAND(displayNotes
, "display all notes", "")
257 log
.displayNL("Displaying %d notes:", Notes
.Notes
.size());
258 for(list
<C3DNotes::CNote
>::iterator it
= Notes
.Notes
.begin(); it
!= Notes
.Notes
.end(); it
++)
260 log
.displayNL("id %d pos(%f,%f,%f) note '%s'", (*it
).Id
, (*it
).Position
.x
, (*it
).Position
.y
, (*it
).Position
.z
, (*it
).Note
.c_str());
266 NLMISC_COMMAND(gotoNote
, "go to a note", "<id>|<text>")
271 CVector
pos(CVector::Null
);
273 sint id
= atoi(args
[0].c_str());
278 for(uint i
= 0; i
< args
.size(); i
++)
280 if(i
!= 0) tok
+= " ";
284 list
<C3DNotes::CNote
>::iterator it
;
285 for(it
= Notes
.Notes
.begin(); it
!= Notes
.Notes
.end(); it
++)
287 string note
= toLower((*it
).Note
);
288 if(note
.find(tok
) != string::npos
)
290 pos
= (*it
).Position
;
294 if(it
== Notes
.Notes
.end())
296 log
.displayNL("No notes match the text '%s'", tok
.c_str());
302 list
<C3DNotes::CNote
>::iterator it
;
303 for(it
= Notes
.Notes
.begin(); it
!= Notes
.Notes
.end(); it
++)
307 pos
= (*it
).Position
;
311 if(it
== Notes
.Notes
.end())
313 log
.displayNL("No notes match the id %d", id
);
317 if(pos
!= CVector::Null
)
322 cmd
= toString("pos %f %f %f", pos
.x
, pos
.y
, pos
.z
);
326 cmd
= toString("a Position %f,%f", pos
.x
, pos
.y
);
328 log
.displayNL("Go to note at position (%f,%f,%f)", pos
.x
, pos
.y
, pos
.z
);
329 ICommand::execute(cmd
, *InfoLog
);
337 NLMISC_COMMAND(debug
, "open the debug window. alias to ah show_hide debug_info", "")
339 if(args
.size() != 0) return false;
340 string
cmd("ah show debug_info");
341 ICommand::execute(cmd
, log
);