void SerialComm::ProcessData() { MessageType code; uint32_t mask; if (!data_input.ParseInto(code, mask)) return; if (code != MessageType::Command) return; uint32_t ack_data{0}; if (mask & COM_SET_EEPROM_DATA && data_input.ParseInto(config->raw)) { writeEEPROM(); // TODO: deal with side effect code ack_data |= COM_SET_EEPROM_DATA; } if (mask & COM_REINIT_EEPROM_DATA) { initializeEEPROM(); // TODO: deal with side effect code writeEEPROM(); // TODO: deal with side effect code } if (mask & COM_REQ_EEPROM_DATA) { SendConfiguration(); ack_data |= COM_REQ_EEPROM_DATA; } if (mask & COM_REQ_ENABLE_ITERATION) { uint8_t flag; if (data_input.ParseInto(flag)) { if (flag == 1) state->processMotorEnablingIteration(); else state->disableMotors(); ack_data |= COM_REQ_ENABLE_ITERATION; } } // This should pass if any motor speed is set if (mask & COM_MOTOR_OVERRIDE_SPEED_ALL) { if (mask & COM_MOTOR_OVERRIDE_SPEED_0 && data_input.ParseInto(state->MotorOut[0])) ack_data |= COM_MOTOR_OVERRIDE_SPEED_0; if (mask & COM_MOTOR_OVERRIDE_SPEED_1 && data_input.ParseInto(state->MotorOut[1])) ack_data |= COM_MOTOR_OVERRIDE_SPEED_1; if (mask & COM_MOTOR_OVERRIDE_SPEED_2 && data_input.ParseInto(state->MotorOut[2])) ack_data |= COM_MOTOR_OVERRIDE_SPEED_2; if (mask & COM_MOTOR_OVERRIDE_SPEED_3 && data_input.ParseInto(state->MotorOut[3])) ack_data |= COM_MOTOR_OVERRIDE_SPEED_3; if (mask & COM_MOTOR_OVERRIDE_SPEED_4 && data_input.ParseInto(state->MotorOut[4])) ack_data |= COM_MOTOR_OVERRIDE_SPEED_4; if (mask & COM_MOTOR_OVERRIDE_SPEED_5 && data_input.ParseInto(state->MotorOut[5])) ack_data |= COM_MOTOR_OVERRIDE_SPEED_5; if (mask & COM_MOTOR_OVERRIDE_SPEED_6 && data_input.ParseInto(state->MotorOut[6])) ack_data |= COM_MOTOR_OVERRIDE_SPEED_6; if (mask & COM_MOTOR_OVERRIDE_SPEED_7 && data_input.ParseInto(state->MotorOut[7])) ack_data |= COM_MOTOR_OVERRIDE_SPEED_7; } if (mask & COM_SET_COMMAND_OVERRIDE) { uint8_t flag; if (data_input.ParseInto(flag)) { if (flag == 1) state->set(STATUS_OVERRIDE); else state->clear(STATUS_OVERRIDE); ack_data |= COM_SET_COMMAND_OVERRIDE; } } if (mask & COM_SET_STATE_MASK) { uint32_t new_state_mask; if (data_input.ParseInto(new_state_mask)) { SetStateMsg(new_state_mask); ack_data |= COM_SET_STATE_MASK; } } if (mask & COM_SET_STATE_DELAY) { uint16_t new_state_delay; if (data_input.ParseInto(new_state_delay)) { send_state_delay = new_state_delay; ack_data |= COM_SET_STATE_DELAY; } } if (mask & COM_REQ_HISTORY) { String eeprom_data; for (size_t i = EEPROM_LOG_START; i < EEPROM_LOG_END; ++i) eeprom_data += char(EEPROM[i]); SendDebugString(eeprom_data, MessageType::HistoryData); ack_data |= COM_REQ_HISTORY; } if (mask & COM_SET_LED) { uint8_t mode, r1, g1, b1, r2, g2, b2, ind_r, ind_g; if (data_input.ParseInto(mode, r1, g1, b1, r2, g2, b2, ind_r, ind_g)) { led->set(LED::Pattern(mode), r1, g1, b1, r2, g2, b2, ind_r, ind_g); ack_data |= COM_SET_LED; } } if (mask & COM_REQ_RESPONSE) { SendResponse(mask, ack_data); } }
/** @brief this에게 발동효과 적용 xApply */ int XSkillReceiver::ApplyInvokeEffect( XSkillDat *pSkillDat, XSkillUser *pCaster, XSkillReceiver* pInvoker, XBuffObj *pBuffObj, const EFFECT *pEffect, int level ) { bool bApplied = false; // 발동조건스킬이 지정되어있을땐 그 스킬(버프)을 인보커가 가지고 있는지 검사해야 한다. if( pEffect->strInvokeIfHaveBuff.empty() == false ) if( !pInvoker->FindBuffSkill( pEffect->strInvokeIfHaveBuff.c_str() ) ) return 0; /* // 효과가 적용될때마다 이벤트를 발생시킨다. // DoT형태의 경우 DoT시점마다 호출되면 만약 발동효과가 2개인경우는 DoT때마다 두번씩 호출된다. */ if( !OnEventApplyInvokeEffect( pCaster, pBuffObj, pSkillDat, pEffect, level ) ) // virtual return 0; // 사용자가 0을 리턴하면 효과 적용시키지 않는다. // 상태발동되어야 할게 있으면 버추얼로 호출시킨다. if( pEffect->invokeState ) { if( OnApplyState( pCaster, pInvoker, pEffect, pEffect->invokeState, IsState(pEffect->invokeState) ) == FALSE ) { // virtual // 상태이상을 저항하면 효과를 적용하지 않는다. return 0; } SetStateMsg( pEffect->invokeState, true ); if( pBuffObj && pBuffObj->IsFirstProcess() ) { OnFirstApplyState( pCaster, pInvoker, pEffect, pEffect->invokeState, IsState(pEffect->invokeState), level ); // virtual bApplied = true; } } // invokeState // 발동스킬이 있는가? if( !pEffect->strInvokeSkill.empty()) { const ID idCallerBuff = (pBuffObj)? pBuffObj->GetidSkill() : 0; // this에게 스킬을 발동스킨다. bApplied = DoInvokeSkill( this, XE::VEC2(), pSkillDat, pEffect, level, pCaster, idCallerBuff ); // _tstring strInvokeSkillMut = pEffect->strInvokeSkill; // // strInvokeSkill이 바뀔수 있음. // bool bInvoke = pInvoker->OnInvokeSkill( pSkillDat, pEffect, this, level, &strInvokeSkillMut ); // if( bInvoke ) { // #ifdef _XSINGLE // // XLOGXN( "스킬발동: %s", pEffect->strInvokeSkill.c_str() ); // #endif // _XSINGLE // // 발동스킬을 실행시킨다. 기준타겟은 this로 된다. // // 발동스킬이 m_listUseSkill에 들어가는 문제가 있어 안들어가도록 수정함. // auto infoUseSkill // = pCaster->UseSkillByIds( strInvokeSkillMut, // 이게 맞는듯. pEffect->strInvokeSkill, // level, // this, nullptr ); // XASSERT( infoUseSkill.errCode == xOK /*|| infoUseSkill.errCode == xERR_ALREADY_APPLY_SKILL*/ ); // const ID idCallerBuff = (pBuffObj)? pBuffObj->GetidSkill() : 0; // if( infoUseSkill.errCode == xOK ) { // // 발동스킬은 지속형일수도 있고 즉시발동형일수도 있다. // pCaster->OnShootSkill( infoUseSkill, idCallerBuff ); // bApplied = true; // } // } } // 효과발동자(시전대상)에게 이 스킬로 부터 발동될 스킬이 있으면 발생시킨다. pInvoker->OnEventInvokeFromSkill( pSkillDat, pEffect, pCaster, this ); // 비보정파라메터와 보정파라메터를 나눠서 버추얼로 처리한다 if( pEffect->invokeParameter < 0 ) { return ApplyEffectNotAdjParam( pSkillDat, pCaster, pEffect, level ); } else if( pEffect->invokeParameter > 0 ) { return ApplyEffectAdjParam( pSkillDat, pCaster, pEffect, level, pBuffObj ); } return bApplied; }