1 /* 2 * OpenClonk, http://www.openclonk.org 3 * 4 * Copyright (c) 1998-2000, Matthes Bender 5 * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ 6 * Copyright (c) 2009-2016, The OpenClonk Team and contributors 7 * 8 * Distributed under the terms of the ISC license; see accompanying file 9 * "COPYING" for details. 10 * 11 * "Clonk" is a registered trademark of Matthes Bender, used with permission. 12 * See accompanying file "TRADEMARK" for details. 13 * 14 * To redistribute this file separately, substitute the full license texts 15 * for the above references. 16 */ 17 18 /* Control packets contain all player input in the message queue */ 19 20 #ifndef INC_C4Control 21 #define INC_C4Control 22 23 #include "control/C4PlayerInfo.h" 24 #include "gui/C4KeyboardInput.h" 25 #include "network/C4PacketBase.h" 26 #include "network/C4Client.h" 27 #include "object/C4Id.h" 28 #include "object/C4ObjectList.h" 29 30 // *** control base classes 31 32 class C4ControlPacket : public C4PacketBase 33 { 34 public: 35 C4ControlPacket(); 36 ~C4ControlPacket() override; 37 38 protected: 39 int32_t iByClient; 40 41 public: getByClient()42 int32_t getByClient() const { return iByClient; } 43 bool LocalControl() const; HostControl()44 bool HostControl() const { return iByClient == C4ClientIDHost; } 45 46 void SetByClient(int32_t iByClient); 47 PreExecute()48 virtual bool PreExecute() const { return true; } 49 virtual void Execute() const = 0; PreRec(C4Record * pRecord)50 virtual void PreRec(C4Record *pRecord) { } 51 52 // allowed in lobby (without dynamic loaded)? Lobby()53 virtual bool Lobby() const { return false; } 54 // allowed as direct/private control? Sync()55 virtual bool Sync() const { return true; } 56 57 void CompileFunc(StdCompiler *pComp) override; 58 }; 59 60 #define DECLARE_C4CONTROL_VIRTUALS \ 61 void Execute() const override; \ 62 void CompileFunc(StdCompiler *pComp) override; 63 64 class C4Control : public C4PacketBase 65 { 66 public: 67 C4Control(); 68 ~C4Control() override; 69 70 protected: 71 C4PacketList Pkts; 72 73 public: 74 75 void Clear(); 76 77 // packet list wrappers firstPkt()78 C4IDPacket *firstPkt() const { return Pkts.firstPkt(); } nextPkt(C4IDPacket * pPkt)79 C4IDPacket *nextPkt(C4IDPacket *pPkt) const { return Pkts.nextPkt(pPkt); } 80 AddHead(C4PacketType eType,C4ControlPacket * pCtrl)81 void AddHead(C4PacketType eType, C4ControlPacket *pCtrl) { Pkts.AddHead(eType, pCtrl); } Add(C4PacketType eType,C4ControlPacket * pCtrl)82 void Add(C4PacketType eType, C4ControlPacket *pCtrl) { Pkts.Add(eType, pCtrl); } 83 Take(C4Control & Ctrl)84 void Take(C4Control &Ctrl) { Pkts.Take(Ctrl.Pkts); } Append(const C4Control & Ctrl)85 void Append(const C4Control &Ctrl) { Pkts.Append(Ctrl.Pkts); } Copy(const C4Control & Ctrl)86 void Copy(const C4Control &Ctrl) { Clear(); Pkts.Append(Ctrl.Pkts); } Remove(C4IDPacket * pPkt)87 void Remove(C4IDPacket *pPkt) { Pkts.Remove(pPkt); } Delete(C4IDPacket * pPkt)88 void Delete(C4IDPacket *pPkt) { Pkts.Delete(pPkt); } 89 90 // control execution 91 bool PreExecute() const; 92 void Execute() const; 93 void PreRec(C4Record *pRecord) const; 94 95 void CompileFunc(StdCompiler *pComp) override; 96 }; 97 98 // *** control packets 99 100 enum C4CtrlValueType 101 { 102 C4CVT_None = -1, 103 C4CVT_ControlRate = 0, 104 C4CVT_DisableDebug = 1, 105 C4CVT_MaxPlayer = 2, 106 C4CVT_TeamDistribution = 3, 107 C4CVT_TeamColors = 4, 108 }; 109 110 class C4ControlSet : public C4ControlPacket // sync, lobby 111 { 112 public: 113 C4ControlSet() = default; C4ControlSet(C4CtrlValueType eValType,int32_t iData)114 C4ControlSet(C4CtrlValueType eValType, int32_t iData) 115 : eValType(eValType), iData(iData) 116 { } 117 protected: 118 C4CtrlValueType eValType{C4CVT_None}; 119 int32_t iData{0}; 120 public: 121 // C4CVT_TeamDistribution and C4CVT_TeamColors are lobby-packets Lobby()122 bool Lobby() const override { return eValType == C4CVT_TeamDistribution || eValType == C4CVT_TeamColors; } 123 124 DECLARE_C4CONTROL_VIRTUALS 125 }; 126 127 class C4ControlScript : public C4ControlPacket // sync 128 { 129 public: 130 enum { SCOPE_Console=-2, SCOPE_Global=-1 }; // special scopes to be passed as target objects 131 132 C4ControlScript() = default; 133 C4ControlScript(const char *szScript, int32_t iTargetObj, bool fUseVarsFromCallerContext = false, bool editor_select_result = false) iTargetObj(iTargetObj)134 : iTargetObj(iTargetObj), fUseVarsFromCallerContext(fUseVarsFromCallerContext), Script(szScript, true), editor_select_result(editor_select_result) 135 { } 136 protected: 137 int32_t iTargetObj{-1}; 138 bool fUseVarsFromCallerContext{false}; 139 bool editor_select_result; // if true and executed script from local client in editor mode, select the object returned by this script 140 StdStrBuf Script; 141 public: SetTargetObj(int32_t iObj)142 void SetTargetObj(int32_t iObj) { iTargetObj = iObj; } 143 DECLARE_C4CONTROL_VIRTUALS 144 }; 145 146 class C4ControlMsgBoardReply : public C4ControlPacket // sync 147 { 148 public: C4ControlMsgBoardReply()149 C4ControlMsgBoardReply() 150 : player(NO_OWNER) 151 {} C4ControlMsgBoardReply(const char * reply,int32_t target,int32_t player)152 C4ControlMsgBoardReply(const char *reply, int32_t target, int32_t player) 153 : reply(reply), target(target), player(player) 154 {} 155 156 private: 157 StdCopyStrBuf reply; 158 int32_t target{-1}; 159 int32_t player; 160 161 public: 162 DECLARE_C4CONTROL_VIRTUALS 163 }; 164 165 class C4ControlMsgBoardCmd : public C4ControlPacket // sync 166 { 167 public: C4ControlMsgBoardCmd()168 C4ControlMsgBoardCmd() 169 : player(NO_OWNER) 170 {} C4ControlMsgBoardCmd(const char * command,const char * parameter,int32_t player)171 C4ControlMsgBoardCmd(const char *command, const char *parameter, int32_t player) 172 : command(command), parameter(parameter), player(player) 173 {} 174 175 private: 176 StdCopyStrBuf command; 177 StdCopyStrBuf parameter; 178 int32_t player; 179 180 public: 181 DECLARE_C4CONTROL_VIRTUALS 182 }; 183 184 class C4ControlPlayerSelect : public C4ControlPacket // sync 185 { 186 public: 187 C4ControlPlayerSelect() = default; 188 C4ControlPlayerSelect(int32_t iPlr, const C4ObjectList &Objs, bool fIsAlt); ~C4ControlPlayerSelect()189 ~C4ControlPlayerSelect() override { delete[] pObjNrs; } 190 protected: 191 int32_t iPlr{-1}; 192 bool fIsAlt{false}; 193 int32_t iObjCnt{0}; 194 int32_t *pObjNrs{nullptr}; 195 public: 196 DECLARE_C4CONTROL_VIRTUALS 197 }; 198 199 class C4ControlPlayerControl : public C4ControlPacket // sync 200 { 201 public: 202 C4ControlPlayerControl() = default; C4ControlPlayerControl(int32_t iPlr,C4PlayerControl::ControlState state,const C4KeyEventData & rExtraData)203 C4ControlPlayerControl(int32_t iPlr, C4PlayerControl::ControlState state, const C4KeyEventData &rExtraData) 204 : iPlr(iPlr), state(state), ExtraData(rExtraData) { } C4ControlPlayerControl(int32_t iPlr,int32_t iControl,int32_t iExtraData)205 C4ControlPlayerControl(int32_t iPlr, int32_t iControl, int32_t iExtraData) // old-style menu com emulation 206 : iPlr(iPlr), state(C4PlayerControl::CONS_Down), ExtraData(iExtraData,0,0,0,0) { AddControl(iControl,0); } 207 208 struct ControlItem 209 { 210 int32_t iControl{-1}; 211 int32_t iTriggerMode{0}; 212 ControlItem() = default; ControlItemControlItem213 ControlItem(int32_t iControl, int32_t iTriggerMode) : iControl(iControl), iTriggerMode(iTriggerMode) {} 214 void CompileFunc(StdCompiler *pComp); 215 bool operator ==(const struct ControlItem &cmp) const { return iControl==cmp.iControl && iTriggerMode == cmp.iTriggerMode; } 216 }; 217 typedef std::vector<ControlItem> ControlItemVec; 218 protected: 219 int32_t iPlr{-1}; 220 int32_t state{C4PlayerControl::CONS_Down}; 221 C4KeyEventData ExtraData; 222 ControlItemVec ControlItems; 223 public: 224 DECLARE_C4CONTROL_VIRTUALS AddControl(int32_t iControl,int32_t iTriggerMode)225 void AddControl(int32_t iControl, int32_t iTriggerMode) 226 { ControlItems.emplace_back(iControl, iTriggerMode); } GetControlItems()227 const ControlItemVec &GetControlItems() const { return ControlItems; } GetState()228 C4PlayerControl::ControlState GetState() const { return static_cast<C4PlayerControl::ControlState>(state); } GetExtraData()229 const C4KeyEventData &GetExtraData() const { return ExtraData; } SetExtraData(const C4KeyEventData & new_extra_data)230 void SetExtraData(const C4KeyEventData &new_extra_data) { ExtraData = new_extra_data; } 231 }; 232 233 class C4ControlPlayerMouse : public C4ControlPacket // sync 234 { 235 public: 236 enum Action 237 { 238 CPM_NoAction = 0, 239 240 CPM_Hover = 0x01, 241 CPM_Drop = 0x02 242 }; 243 C4ControlPlayerMouse()244 C4ControlPlayerMouse() : player(NO_OWNER) {} 245 static C4ControlPlayerMouse *Hover(const C4Player *player, const C4Object *target, const C4Object *old_target, const C4Object *drag = nullptr); 246 static C4ControlPlayerMouse *DragDrop(const C4Player *player, const C4Object *target, const C4Object *drag); 247 248 private: 249 int32_t action{CPM_NoAction}; 250 int32_t player; 251 int32_t target_obj{0}; 252 int32_t drag_obj{0}; 253 int32_t old_obj{0}; 254 public: 255 DECLARE_C4CONTROL_VIRTUALS 256 }; 257 258 class C4ControlMenuCommand : public C4ControlPacket // sync 259 { 260 public: 261 C4ControlMenuCommand() = default; 262 C4ControlMenuCommand(int32_t actionID, int32_t player, int32_t menuID, int32_t subwindowID, 263 C4Object *target, int32_t actionType); 264 protected: 265 int32_t actionID, player, menuID{0}, subwindowID{0}, target, actionType; 266 public: 267 DECLARE_C4CONTROL_VIRTUALS 268 }; 269 270 class C4ControlPlayerAction : public C4ControlPacket // sync 271 { 272 public: 273 enum Action 274 { 275 CPA_NoAction = 0, 276 277 CPA_Surrender = 0x01, 278 CPA_ActivateGoal = 0x02, 279 CPA_ActivateGoalMenu = 0x03, 280 CPA_Eliminate = 0x04, 281 282 CPA_SetHostility = 0x10, 283 CPA_SetTeam = 0x11, 284 285 CPA_InitScenarioPlayer = 0x20, 286 CPA_InitPlayerControl = 0x21 287 }; 288 289 C4ControlPlayerAction(const C4Player *source = nullptr); 290 static C4ControlPlayerAction *Surrender(const C4Player *source); 291 static C4ControlPlayerAction *Eliminate(const C4Player *source); 292 static C4ControlPlayerAction *ActivateGoalMenu(const C4Player *source); 293 static C4ControlPlayerAction *ActivateGoal(const C4Player *source, const C4Object *target); 294 static C4ControlPlayerAction *SetHostility(const C4Player *source, const C4Player *target, bool hostile); 295 static C4ControlPlayerAction *SetTeam(const C4Player *source, int32_t team); 296 static C4ControlPlayerAction *InitScenarioPlayer(const C4Player *source, int32_t team); 297 static C4ControlPlayerAction *InitPlayerControl(const C4Player *source, const C4PlayerControlAssignmentSet *ctrl_set = nullptr); 298 299 private: 300 Action action{CPA_NoAction}; 301 int32_t source; 302 int32_t target; 303 int32_t param_int{0}; 304 StdCopyStrBuf param_str; 305 306 enum IpcParam 307 { 308 CPA_IPC_HasKeyboard = 1<<0, 309 CPA_IPC_HasMouse = 1<<1, 310 CPA_IPC_HasGamepad = 1<<2 311 }; 312 313 public: 314 DECLARE_C4CONTROL_VIRTUALS 315 }; 316 317 class C4ControlSyncCheck : public C4ControlPacket // not sync 318 { 319 public: 320 C4ControlSyncCheck(); 321 protected: 322 int32_t Frame; 323 int32_t ControlTick; 324 int32_t RandomCount; 325 int32_t AllCrewPosX; 326 int32_t PXSCount; 327 int32_t MassMoverIndex; 328 int32_t ObjectCount; 329 int32_t ObjectEnumerationIndex; 330 int32_t SectShapeSum; 331 public: 332 void Set(); getFrame()333 int32_t getFrame() const { return Frame; } Sync()334 bool Sync() const override { return false; } 335 DECLARE_C4CONTROL_VIRTUALS 336 protected: 337 static int32_t GetAllCrewPosX(); 338 }; 339 340 class C4ControlSynchronize : public C4ControlPacket // sync 341 { 342 public: 343 C4ControlSynchronize(bool fSavePlrFiles = false, bool fSyncClearance = false) fSavePlrFiles(fSavePlrFiles)344 : fSavePlrFiles(fSavePlrFiles), fSyncClearance(fSyncClearance) 345 { } 346 protected: 347 bool fSavePlrFiles, fSyncClearance; 348 public: 349 DECLARE_C4CONTROL_VIRTUALS 350 }; 351 352 class C4ControlClientJoin : public C4ControlPacket // not sync, lobby 353 { 354 public: 355 C4ControlClientJoin() = default; C4ControlClientJoin(const C4ClientCore & Core)356 C4ControlClientJoin(const C4ClientCore &Core) : Core(Core) { } 357 public: 358 C4ClientCore Core; 359 public: Sync()360 bool Sync() const override { return false; } Lobby()361 bool Lobby() const override { return true; } 362 DECLARE_C4CONTROL_VIRTUALS 363 }; 364 365 enum C4ControlClientUpdType 366 { 367 CUT_None = -1, CUT_Activate = 0, CUT_SetObserver = 1, CUT_SetReady = 2 368 }; 369 370 class C4ControlClientUpdate : public C4ControlPacket // sync, lobby 371 { 372 public: 373 C4ControlClientUpdate() = default; 374 C4ControlClientUpdate(int32_t iID, C4ControlClientUpdType eType, int32_t iData = 0) iID(iID)375 : iID(iID), eType(eType), iData(iData) 376 { } 377 private: 378 static const int32_t MinReadyAnnouncementDelay = 1; // seconds that need to pass between ready-state announcements to prevent spam 379 public: 380 int32_t iID{0}; 381 C4ControlClientUpdType eType{CUT_None}; 382 int32_t iData{0}; 383 public: Sync()384 bool Sync() const override { return false; } Lobby()385 bool Lobby() const override { return true; } 386 DECLARE_C4CONTROL_VIRTUALS 387 }; 388 389 class C4ControlClientRemove : public C4ControlPacket // not sync, lobby 390 { 391 public: 392 C4ControlClientRemove() = default; iID(iID)393 C4ControlClientRemove(int32_t iID, const char *szReason = "") : iID(iID), strReason(szReason) { } 394 public: 395 int32_t iID; 396 StdCopyStrBuf strReason; 397 public: Sync()398 bool Sync() const override { return false; } Lobby()399 bool Lobby() const override { return true; } 400 DECLARE_C4CONTROL_VIRTUALS 401 }; 402 403 // control used for initial player info, as well as for player info updates 404 class C4ControlPlayerInfo : public C4ControlPacket // not sync, lobby 405 { 406 public: 407 C4ControlPlayerInfo() = default; C4ControlPlayerInfo(const C4ClientPlayerInfos & PlrInfo)408 C4ControlPlayerInfo(const C4ClientPlayerInfos &PlrInfo) 409 : PlrInfo(PlrInfo) 410 { } 411 protected: 412 C4ClientPlayerInfos PlrInfo; 413 public: GetInfo()414 const C4ClientPlayerInfos &GetInfo() const { return PlrInfo; } Sync()415 bool Sync() const override { return false; } Lobby()416 bool Lobby() const override { return true; } 417 DECLARE_C4CONTROL_VIRTUALS 418 }; 419 420 struct C4ControlJoinPlayer : public C4ControlPacket // sync 421 { 422 public: 423 C4ControlJoinPlayer() = default; 424 C4ControlJoinPlayer(const char *szFilename, int32_t iAtClient, int32_t iIDInfo, C4Network2ResCore ResCore); 425 C4ControlJoinPlayer(const char *szFilename, int32_t iAtClient, int32_t iIDInfo); 426 protected: 427 StdStrBuf Filename; 428 int32_t iAtClient{-1}; 429 int32_t idInfo{-1}; 430 bool fByRes{false}; 431 StdBuf PlrData; // for fByRes == false 432 C4Network2ResCore ResCore; // for fByRes == true 433 public: 434 DECLARE_C4CONTROL_VIRTUALS 435 bool PreExecute() const override; 436 void PreRec(C4Record *pRecord) override; 437 void Strip(); 438 }; 439 440 enum C4ControlEMObjectAction 441 { 442 EMMO_Move, // move objects by offset 443 EMMO_MoveForced,// move objects by offset and ignore HorizontalFixed 444 EMMO_Enter, // enter objects into iTargetObj 445 EMMO_Duplicate, // duplicate objects at same position; reset EditCursor 446 EMMO_Script, // execute Script 447 EMMO_Remove, // remove objects 448 EMMO_Exit, // exit objects 449 EMMO_Create, // create a new object (used by C4Game::DropDef) 450 EMMO_Transform // adjust rotation / con of selected object 451 }; 452 453 class C4ControlEMMoveObject : public C4ControlPacket // sync 454 { 455 public: C4ControlEMMoveObject()456 C4ControlEMMoveObject() : tx(Fix0), ty(Fix0) { } 457 C4ControlEMMoveObject(C4ControlEMObjectAction eAction, C4Real tx, C4Real ty, C4Object *pTargetObj, 458 int32_t iObjectNum = 0, int32_t *pObjects = nullptr, const char *szScript = nullptr, bool drag_finished = false); 459 static C4ControlEMMoveObject *CreateObject(const C4ID &id, C4Real x, C4Real y, C4Object *container); 460 ~C4ControlEMMoveObject() override; 461 protected: 462 C4ControlEMObjectAction eAction{EMMO_Move}; // action to be performed 463 C4Real tx,ty; // target position 464 int32_t iTargetObj{0}; // enumerated ptr to target object 465 int32_t iObjectNum{0}; // number of objects moved 466 int32_t *pObjects{nullptr}; // pointer on array of objects moved 467 StdStrBuf StringParam; // script to execute, or ID of object to create 468 bool drag_finished{false}; // Movement only: Set when mouse drag operation concluded (i.e. mouse up) 469 private: 470 void MoveObject(C4Object *moved_object, bool move_forced) const; 471 public: 472 DECLARE_C4CONTROL_VIRTUALS 473 }; 474 475 enum C4ControlEMDrawAction 476 { 477 EMDT_SetMode, // set new landscape mode 478 EMDT_Brush, // drawing tool 479 EMDT_Fill, // drawing tool 480 EMDT_Line, // drawing tool 481 EMDT_Rect // drawing tool 482 }; 483 484 enum class LandscapeMode; 485 class C4ControlEMDrawTool : public C4ControlPacket // sync 486 { 487 public: 488 C4ControlEMDrawTool() = default; 489 C4ControlEMDrawTool(C4ControlEMDrawAction eAction, LandscapeMode iMode, 490 int32_t iX=-1, int32_t iY=-1, int32_t iX2=-1, int32_t iY2=-1, int32_t iGrade=-1, 491 const char *szMaterial=nullptr, const char *szTexture=nullptr, 492 const char *szBackMaterial=nullptr, const char *szBackTexture=nullptr); 493 protected: 494 C4ControlEMDrawAction eAction{EMDT_SetMode}; // action to be performed 495 LandscapeMode iMode; // new mode, or mode action was performed in (action will fail if changed) 496 int32_t iX{0},iY{0},iX2{0},iY2{0},iGrade{0}; // drawing parameters 497 StdStrBuf Material; // used material 498 StdStrBuf Texture; // used texture 499 StdStrBuf BackMaterial; // used background material 500 StdStrBuf BackTexture; // used background texture 501 public: 502 DECLARE_C4CONTROL_VIRTUALS 503 }; 504 505 enum C4ControlMessageType 506 { 507 C4CMT_Normal = 0, 508 C4CMT_Me = 1, 509 C4CMT_Say = 2, 510 C4CMT_Team = 3, 511 C4CMT_Private = 4, 512 C4CMT_Sound = 5, // "message" is played as a sound instead 513 C4CMT_Alert = 6, // no message. just flash taskbar for inactive clients. 514 C4CMT_System = 10 515 }; 516 517 class C4ControlMessage : public C4ControlPacket // not sync, lobby 518 { 519 public: 520 C4ControlMessage() = default; 521 C4ControlMessage(C4ControlMessageType eType, const char *szMessage, int32_t iPlayer = -1, int32_t iToPlayer = -1) eType(eType)522 : eType(eType), iPlayer(iPlayer), iToPlayer(iToPlayer), Message(szMessage, true) 523 { } 524 protected: 525 C4ControlMessageType eType{C4CMT_Normal}; 526 int32_t iPlayer{-1}, iToPlayer; 527 StdStrBuf Message; 528 public: Sync()529 bool Sync() const override { return false; } Lobby()530 bool Lobby() const override { return true; } 531 DECLARE_C4CONTROL_VIRTUALS 532 }; 533 534 class C4ControlRemovePlr : public C4ControlPacket // sync 535 { 536 public: 537 C4ControlRemovePlr() = default; C4ControlRemovePlr(int32_t iPlr,bool fDisconnected)538 C4ControlRemovePlr(int32_t iPlr, bool fDisconnected) 539 : iPlr(iPlr), fDisconnected(fDisconnected) { } 540 protected: 541 int32_t iPlr{-1}; 542 bool fDisconnected{false}; 543 public: 544 DECLARE_C4CONTROL_VIRTUALS 545 }; 546 547 class C4ControlDebugRec : public C4ControlPacket // sync 548 { 549 public: 550 C4ControlDebugRec() = default; C4ControlDebugRec(StdBuf & Data)551 C4ControlDebugRec(StdBuf &Data) 552 : Data(Data) { } 553 protected: 554 StdBuf Data; 555 public: 556 DECLARE_C4CONTROL_VIRTUALS 557 }; 558 559 enum C4ControlVoteType 560 { 561 VT_None = -1, 562 VT_Cancel, 563 VT_Kick, 564 VT_Pause 565 }; 566 567 class C4ControlVote : public C4ControlPacket 568 { 569 public: 570 C4ControlVote(C4ControlVoteType eType = VT_None, bool fApprove = true, int iData = 0) eType(eType)571 : eType(eType), fApprove(fApprove), iData(iData) 572 { } 573 574 private: 575 C4ControlVoteType eType; 576 bool fApprove; 577 int32_t iData; 578 579 public: getType()580 C4ControlVoteType getType() const { return eType; } isApprove()581 bool isApprove() const { return fApprove; } getData()582 int32_t getData() const { return iData; } 583 584 StdStrBuf getDesc() const; 585 StdStrBuf getDescWarning() const; 586 Sync()587 bool Sync() const override { return false; } 588 589 DECLARE_C4CONTROL_VIRTUALS 590 }; 591 592 class C4ControlVoteEnd : public C4ControlVote 593 { 594 public: 595 C4ControlVoteEnd(C4ControlVoteType eType = VT_None, bool fApprove = true, int iData = 0) C4ControlVote(eType,fApprove,iData)596 : C4ControlVote(eType, fApprove, iData) 597 { } 598 Sync()599 bool Sync() const override { return true; } 600 601 DECLARE_C4CONTROL_VIRTUALS 602 }; 603 604 struct C4ControlReInitScenario : public C4ControlPacket // sync 605 { 606 public: 607 C4ControlReInitScenario(); 608 protected: 609 StdBuf data; 610 public: 611 DECLARE_C4CONTROL_VIRTUALS 612 }; 613 614 class C4ControlEditGraph : public C4ControlPacket // sync 615 { 616 public: 617 enum Action 618 { 619 CEG_None=0, 620 CEG_SetVertexPos, 621 CEG_EditEdge, 622 CEG_InsertVertex, 623 CEG_InsertEdge, 624 CEG_RemoveVertex, 625 CEG_RemoveEdge 626 }; 627 C4ControlEditGraph() = default; C4ControlEditGraph(const char * path,Action action,int32_t index,int32_t x,int32_t y)628 C4ControlEditGraph(const char *path, Action action, int32_t index, int32_t x, int32_t y) 629 : path(path), action(action), index(index), x(x), y(y) { } 630 private: 631 StdCopyStrBuf path; 632 Action action=CEG_None; 633 int32_t index=-1, x=0, y=0; 634 public: 635 DECLARE_C4CONTROL_VIRTUALS 636 GetPath()637 const char *GetPath() const { return path.getData(); } GetAction()638 Action GetAction() const { return action; } GetIndex()639 int32_t GetIndex() const { return index; } GetX()640 int32_t GetX() const { return x; } GetY()641 int32_t GetY() const { return y; } 642 }; 643 644 #endif 645