void Vehicle::RemovePassenger(Unit* unit) { if (unit->GetVehicle() != this) return; SeatMap::iterator seat = GetSeatIteratorForPassenger(unit); ASSERT(seat != Seats.end()); sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s exit vehicle entry %u id %u dbguid %u seat %d", unit->GetName().c_str(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUIDLow(), (int32)seat->first); seat->second.Passenger = 0; if (seat->second.SeatInfo->CanEnterOrExit() && ++UsableSeatNum) _me->SetFlag(UNIT_NPC_FLAGS, (_me->GetTypeId() == TYPEID_PLAYER ? UNIT_NPC_FLAG_PLAYER_VEHICLE : UNIT_NPC_FLAG_SPELLCLICK)); unit->ClearUnitState(UNIT_STATE_ONVEHICLE); if (_me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER && seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL) _me->RemoveCharmedBy(unit); if (_me->IsInWorld()) { unit->m_movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); unit->m_movementInfo.t_time = 0; unit->m_movementInfo.t_seat = 0; } // only for flyable vehicles if (unit->IsFlying()) _me->CastSpell(unit, VEHICLE_SPELL_PARACHUTE, true); if (_me->GetTypeId() == TYPEID_UNIT && _me->ToCreature()->IsAIEnabled) _me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, false); if (GetBase()->GetTypeId() == TYPEID_UNIT) sScriptMgr->OnRemovePassenger(this, unit); }
void SrtmTile::Init(string const & dir, ms::LatLon const & coord) { Invalidate(); string const base = GetBase(coord); string const cont = dir + base + ".SRTMGL1.hgt.zip"; string file = base + ".hgt"; UnzipMemDelegate delegate(m_data); try { ZipFileReader::UnzipFile(cont, file, delegate); } catch (ZipFileReader::LocateZipException const & e) { // Sometimes packed file has different name. See N39E051 measure. file = base + ".SRTMGL1.hgt"; ZipFileReader::UnzipFile(cont, file, delegate); } if (!delegate.m_completed) { LOG(LWARNING, ("Can't decompress SRTM file:", cont)); Invalidate(); return; } if (m_data.size() != kSrtmTileSize) { LOG(LWARNING, ("Bad decompressed SRTM file size:", cont, m_data.size())); Invalidate(); return; } m_valid = true; }
/* * Handle UDN_DELTAPOS notification. */ void MySpinCtrl::OnDeltaPos(NMHDR* pNMHDR, LRESULT* pResult) { _ASSERTE(! (UDS_SETBUDDYINT & GetStyle()) && "'Auto Buddy Int' style *MUST* be unchecked"); // _ASSERTE( (UDS_AUTOBUDDY & GetStyle()) && "'Auto Buddy' style *MUST* be checked"); _ASSERTE( (UDS_NOTHOUSANDS & GetStyle()) && "'No Thousands' style *MUST* be checked"); NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; /* grab value from buddy ctrl */ ASSERT(GetBuddy() != NULL); CString buddyStr; GetBuddy()->GetWindowText(buddyStr); long buddyVal, proposedVal; if (!ConvLong(buddyStr, &buddyVal)) goto bail; // bad string proposedVal = buddyVal - pNMUpDown->iDelta; /* peg at the end */ if (proposedVal < fLow) proposedVal = fLow; if (proposedVal > fHigh) proposedVal = fHigh; if (proposedVal != buddyVal) { /* set buddy control to new value */ if (GetBase() == 10) buddyStr.Format(L"%d", proposedVal); else buddyStr.Format(L"%X", proposedVal); GetBuddy()->SetWindowText(buddyStr); } bail: *pResult = 0; }
uint16 GetEvasion(CMobEntity* PMob) { uint8 evaRank = PMob->evaRank; // Mob evasion is based on job // but occasionally war mobs // might have a different rank switch (PMob->GetMJob()) { case JOB_THF: case JOB_NIN: evaRank = 1; break; case JOB_MNK: case JOB_DNC: case JOB_SAM: case JOB_PUP: case JOB_RUN: evaRank = 2; break; case JOB_RDM: case JOB_BRD: case JOB_GEO: case JOB_COR: evaRank = 4; break; case JOB_WHM: case JOB_SCH: case JOB_RNG: case JOB_SMN: case JOB_BLM: evaRank = 5; break; } return GetBase(PMob, evaRank); }
int CImage::GetDirtyState() { LPOBJECT lpObject = NULL; int dirty = NO; int ObjDirty; while (lpObject = GetNextObject(lpObject, YES, NO)) { if (Control.UndoObjects && !IsSelectedObject(lpObject)) continue; if (lpObject->DataDirty) ObjDirty = lpObject->DataDirty; else if ((lpObject != GetBase()) && lpObject->lpAlpha && lpObject->AlphaDirty) ObjDirty = lpObject->AlphaDirty; else continue; if (!dirty) dirty = ObjDirty; else if (ObjDirty != dirty) return(IDS_EDITS); } return(dirty); }
void Vehicle::RelocatePassengers() { ASSERT(_me->GetMap()); std::vector<std::pair<Unit*, Position>> seatRelocation; seatRelocation.reserve(Seats.size()); // not sure that absolute position calculation is correct, it must depend on vehicle pitch angle for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr) { if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), itr->second.Passenger.Guid)) { ASSERT(passenger->IsInWorld()); float px, py, pz, po; passenger->m_movementInfo.transport.pos.GetPosition(px, py, pz, po); CalculatePassengerPosition(px, py, pz, &po); seatRelocation.emplace_back(passenger, Position(px, py, pz, po)); } } for (auto const& pair : seatRelocation) pair.first->UpdatePosition(pair.second); }
void BookCtrlBaseTestCase::Selection() { wxBookCtrlBase * const base = GetBase(); base->SetSelection(0); CPPUNIT_ASSERT_EQUAL(0, base->GetSelection()); CPPUNIT_ASSERT_EQUAL(wxStaticCast(m_panel1, wxWindow), base->GetCurrentPage()); base->AdvanceSelection(false); CPPUNIT_ASSERT_EQUAL(2, base->GetSelection()); CPPUNIT_ASSERT_EQUAL(wxStaticCast(m_panel3, wxWindow), base->GetCurrentPage()); base->AdvanceSelection(); CPPUNIT_ASSERT_EQUAL(0, base->GetSelection()); CPPUNIT_ASSERT_EQUAL(wxStaticCast(m_panel1, wxWindow), base->GetCurrentPage()); base->ChangeSelection(1); CPPUNIT_ASSERT_EQUAL(1, base->GetSelection()); CPPUNIT_ASSERT_EQUAL(wxStaticCast(m_panel2, wxWindow), base->GetCurrentPage()); }
BOOL CImage::GetUndoState() { LPOBJECT lpObject = NULL; BOOL ObjUndoNotRedo; int UndoNotRedo = -1; while (lpObject = GetNextObject(lpObject, YES, NO)) { if (Control.UndoObjects && !IsSelectedObject(lpObject)) continue; if (lpObject->DataDirty) ObjUndoNotRedo = lpObject->DataUndoNotRedo; else if ((lpObject != GetBase()) && lpObject->lpAlpha && lpObject->AlphaDirty) ObjUndoNotRedo = lpObject->AlphaUndoNotRedo; else continue; if (UndoNotRedo < 0) UndoNotRedo = ObjUndoNotRedo; else if (ObjUndoNotRedo != UndoNotRedo) return(TRUE); } return(UndoNotRedo); }
VehicleKit::VehicleKit(Unit* base, VehicleEntry const* entry) : TransportBase(base), m_vehicleEntry(entry), m_uiNumFreeSeats(0), m_isInitialized(false) { for (uint32 i = 0; i < MAX_VEHICLE_SEAT; ++i) { uint32 seatId = GetEntry()->m_seatID[i]; if (!seatId) continue; if (VehicleSeatEntry const *seatInfo = sVehicleSeatStore.LookupEntry(seatId)) { m_Seats.insert(std::make_pair(i, VehicleSeat(seatInfo))); if (seatInfo->IsUsable()) ++m_uiNumFreeSeats; } } if (base) { if (GetEntry()->m_flags & VEHICLE_FLAG_NO_STRAFE) GetBase()->m_movementInfo.AddMovementFlag2(MOVEFLAG2_NO_STRAFE); if (GetEntry()->m_flags & VEHICLE_FLAG_NO_JUMPING) GetBase()->m_movementInfo.AddMovementFlag2(MOVEFLAG2_NO_JUMPING); if (GetEntry()->m_flags & VEHICLE_FLAG_FULLSPEEDTURNING) GetBase()->m_movementInfo.AddMovementFlag2(MOVEFLAG2_FULLSPEEDTURNING); if (GetEntry()->m_flags & VEHICLE_FLAG_ALLOW_PITCHING) GetBase()->m_movementInfo.AddMovementFlag2(MOVEFLAG2_ALLOW_PITCHING); if (GetEntry()->m_flags & VEHICLE_FLAG_FULLSPEEDPITCHING) { GetBase()->m_movementInfo.AddMovementFlag2(MOVEFLAG2_ALLOW_PITCHING); GetBase()->m_movementInfo.AddMovementFlag2(MOVEFLAG2_FULLSPEEDPITCHING); } } SetDestination(); }
bool Vehicle::AddPassenger(Unit *unit, int8 seatId, bool byAura) { if (unit->GetVehicle() != this) return false; if (unit->GetTypeId() == TYPEID_PLAYER && unit->GetMap()->IsBattleArena()) return false; SeatMap::iterator seat; if (seatId < 0) // no specific seat requirement { for (seat = m_Seats.begin(); seat != m_Seats.end(); ++seat) if (!seat->second.passenger && ((!byAura && seat->second.seatInfo->CanEnterOrExit()) || (byAura && seat->second.seatInfo->IsUsableByAura()))) break; if (seat == m_Seats.end()) // no available seat return false; } else { seat = m_Seats.find(seatId); if (seat == m_Seats.end()) return false; if (seat->second.passenger) seat->second.passenger->ExitVehicle(); else seat->second.passenger = NULL; ASSERT(!seat->second.passenger); } sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s enter vehicle entry %u id %u dbguid %u seat %d", unit->GetName(), me->GetEntry(), m_vehicleInfo->m_ID, me->GetGUIDLow(), (int32) seat->first); seat->second.passenger = unit; if (seat->second.seatInfo->CanEnterOrExit()) { ASSERT(m_usableSeatNum); --m_usableSeatNum; if (!m_usableSeatNum) { if (me->GetTypeId() == TYPEID_PLAYER) me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE); else me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); } } if (seat->second.seatInfo->m_flags && !(seat->second.seatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK11)) unit->AddUnitState( UNIT_STAT_ONVEHICLE); unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT | MOVEMENTFLAG_ROOT); VehicleSeatEntry const *veSeat = seat->second.seatInfo; unit->m_movementInfo.t_pos.m_positionX = veSeat->m_attachmentOffsetX; unit->m_movementInfo.t_pos.m_positionY = veSeat->m_attachmentOffsetY; unit->m_movementInfo.t_pos.m_positionZ = veSeat->m_attachmentOffsetZ; unit->m_movementInfo.t_pos.m_orientation = 0; unit->m_movementInfo.t_time = 0; // 1 for player unit->m_movementInfo.t_seat = seat->first; if (me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL) { if (!me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE)) ASSERT(false); if (VehicleScalingInfo const *scalingInfo = sObjectMgr->GetVehicleScalingInfo(m_vehicleInfo->m_ID)) { Player *plr = unit->ToPlayer(); float averageItemLevel = plr->GetAverageItemLevel(); if (averageItemLevel < scalingInfo->baseItemLevel) averageItemLevel = scalingInfo->baseItemLevel; averageItemLevel -= scalingInfo->baseItemLevel; m_bonusHP = uint32( me->GetMaxHealth() * (averageItemLevel * scalingInfo->scalingFactor)); me->SetMaxHealth(me->GetMaxHealth() + m_bonusHP); me->SetHealth(me->GetHealth() + m_bonusHP); } } if (me->IsInWorld()) { unit->SendMonsterMoveTransport(me); if (me->GetTypeId() == TYPEID_UNIT) { if (me->ToCreature()->IsAIEnabled) me->ToCreature()->AI()->PassengerBoarded( unit, seat->first, true); // update all passenger's positions RelocatePassengers(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); } } unit->DestroyForNearbyPlayers(); unit->UpdateObjectVisibility(false); if (GetBase()->GetTypeId() == TYPEID_UNIT) sScriptMgr->OnAddPassenger(this, unit, seatId); return true; }
Vehicle::~Vehicle() { for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr) { if (itr->second.Passenger) sLog->outError("Vehicle::~Vehicle() | passenger (%s), Base (%s), BaseEntry (%u), MapId (%u)", ObjectAccessor::GetUnit(*GetBase(), itr->second.Passenger) ? ObjectAccessor::GetUnit(*GetBase(), itr->second.Passenger)->GetName() : "n/a", GetBase()->GetName(), GetBase()->GetEntry(), GetBase()->GetMapId()); ASSERT(!itr->second.Passenger); } }
// RAGE AGAINST THE VIRTUAL MACHINE =) gmThread::State gmThread::Sys_Execute(gmVariable * a_return) { register union { const gmuint8 * instruction; const gmuint32 * instruction32; }; register gmVariable * top; gmVariable * base; gmVariable * operand; const gmuint8 * code; if(m_state != RUNNING) return m_state; #if GMDEBUG_SUPPORT if(m_debugFlags && m_machine->GetDebugMode() && m_machine->m_isBroken) { if(m_machine->m_isBroken(this)) return RUNNING; } #endif // GMDEBUG_SUPPORT // make sure we have a stack frame GM_ASSERT(m_frame); GM_ASSERT(GetFunction()->m_type == GM_FUNCTION); // cache our "registers" gmFunctionObject * fn = (gmFunctionObject *) GM_MOBJECT(m_machine, GetFunction()->m_value.m_ref); code = (const gmuint8 *) fn->GetByteCode(); if(m_instruction == NULL) instruction = code; else instruction = m_instruction; top = GetTop(); base = GetBase(); // // start byte code execution // for(;;) { #ifdef GM_CHECK_USER_BREAK_CALLBACK // This may be defined in gmConfig_p.h // Check external source to break execution with exception eg. Check for CTRL-BREAK // Endless loop protection could be implemented with this, or in a similar manner. if( gmMachine::s_userBreakCallback && gmMachine::s_userBreakCallback(this) ) { GMTHREAD_LOG("User break. Execution halted."); goto LabelException; } #endif //GM_CHECK_USER_BREAK_CALLBACK switch(*(instruction32++)) { // // unary operator // #if GM_USE_INCDECOPERATORS case BC_OP_INC : case BC_OP_DEC : #endif case BC_BIT_INV : case BC_OP_NEG : case BC_OP_POS : case BC_OP_NOT : { operand = top - 1; gmOperatorFunction op = OPERATOR(operand->m_type, (gmOperator) instruction32[-1]); if(op) { op(this, operand); } else if((fn = CALLOPERATOR(operand->m_type, (gmOperator) instruction32[-1]))) { operand[2] = operand[0]; operand[0] = gmVariable(GM_NULL, 0); operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); SetTop(operand + 3); State res = PushStackFrame(1, &instruction, &code); top = GetTop(); base = GetBase(); if(res == RUNNING) break; if(res == SYS_YIELD) return RUNNING; if(res == SYS_EXCEPTION) goto LabelException; if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread return res; } else { GMTHREAD_LOG("unary operator %s undefined for type %s", gmGetOperatorName((gmOperator) instruction32[-1]), m_machine->GetTypeName(operand->m_type)); goto LabelException; } break; } // // operator // case BC_OP_ADD : case BC_OP_SUB : case BC_OP_MUL : case BC_OP_DIV : case BC_OP_REM : case BC_BIT_OR : case BC_BIT_XOR : case BC_BIT_AND : case BC_BIT_SHL : case BC_BIT_SHR : case BC_OP_LT : case BC_OP_GT : case BC_OP_LTE : case BC_OP_GTE : case BC_OP_EQ : case BC_OP_NEQ : { operand = top - 2; --top; // NOTE: Classic logic for operators. Higher type processes the operation. register gmType t1 = operand[1].m_type; if(operand->m_type > t1) t1 = operand->m_type; gmOperatorFunction op = OPERATOR(t1, (gmOperator) instruction32[-1]); if(op) { op(this, operand); } else if((fn = CALLOPERATOR(t1, (gmOperator) instruction32[-1]))) { operand[2] = operand[0]; operand[3] = operand[1]; operand[0] = gmVariable(GM_NULL, 0); operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); SetTop(operand + 4); State res = PushStackFrame(2, &instruction, &code); top = GetTop(); base = GetBase(); if(res == RUNNING) break; if(res == SYS_YIELD) return RUNNING; if(res == SYS_EXCEPTION) goto LabelException; if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread return res; } else { GMTHREAD_LOG("operator %s undefined for type %s and %s", gmGetOperatorName((gmOperator) instruction32[-1]), m_machine->GetTypeName(operand->m_type), m_machine->GetTypeName((operand + 1)->m_type)); goto LabelException; } break; } case BC_GETIND : { operand = top - 2; --top; gmOperatorFunction op = OPERATOR(operand->m_type, (gmOperator) instruction32[-1]); if(op) { op(this, operand); } else if((fn = CALLOPERATOR(operand->m_type, (gmOperator) instruction32[-1]))) { operand[2] = operand[0]; operand[3] = operand[1]; operand[0] = gmVariable(GM_NULL, 0); operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); SetTop(operand + 4); State res = PushStackFrame(2, &instruction, &code); top = GetTop(); base = GetBase(); if(res == RUNNING) break; if(res == SYS_YIELD) return RUNNING; if(res == SYS_EXCEPTION) goto LabelException; if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread return res; } else { GMTHREAD_LOG("operator %s undefined for type %s and %s", gmGetOperatorName((gmOperator) instruction32[-1]), m_machine->GetTypeName(operand->m_type), m_machine->GetTypeName((operand + 1)->m_type)); goto LabelException; } break; } case BC_SETIND : { operand = top - 3; top -= 3; gmOperatorFunction op = OPERATOR(operand->m_type, O_SETIND); if(op) { op(this, operand); } else if((fn = CALLOPERATOR(operand->m_type, O_SETIND))) { operand[4] = operand[2]; operand[3] = operand[1]; operand[2] = operand[0]; operand[0] = gmVariable(GM_NULL, 0); operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); SetTop(operand + 5); State res = PushStackFrame(3, &instruction, &code); top = GetTop(); base = GetBase(); if(res == RUNNING) break; if(res == SYS_YIELD) return RUNNING; if(res == SYS_EXCEPTION) goto LabelException; if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread return res; } else { GMTHREAD_LOG("setind failed."); goto LabelException; } break; } case BC_NOP : { break; } case BC_LINE : { #if GMDEBUG_SUPPORT if(m_machine->GetDebugMode() && m_machine->m_line) { SetTop(top); m_instruction = instruction; if(m_machine->m_line(this)) return RUNNING; } #endif // GMDEBUG_SUPPORT break; } case BC_GETDOT : { operand = top - 1; gmptr member = OPCODE_PTR(instruction); top->m_type = GM_STRING; top->m_value.m_ref = member; gmType t1 = operand->m_type; gmOperatorFunction op = OPERATOR(t1, O_GETDOT); if(op) { op(this, operand); if(operand->m_type) break; } if(t1 == GM_NULL) { GMTHREAD_LOG("getdot failed."); goto LabelException; } *operand = m_machine->GetTypeVariable(t1, gmVariable(GM_STRING, member)); break; } case BC_SETDOT : { operand = top - 2; gmptr member = OPCODE_PTR(instruction); top->m_type = GM_STRING; top->m_value.m_ref = member; top -= 2; gmOperatorFunction op = OPERATOR(operand->m_type, O_SETDOT); if(op) { op(this, operand); } else { GMTHREAD_LOG("setdot failed."); goto LabelException; } break; } case BC_BRA : { instruction = code + OPCODE_PTR_NI(instruction); break; } case BC_BRZ : { #if GM_BOOL_OP operand = top - 1; --top; if (operand->m_type > GM_USER) { // Look for overridden operator. gmOperatorFunction op = OPERATOR(operand->m_type, O_BOOL); if (op) { op(this, operand); } else if ((fn = CALLOPERATOR(operand->m_type, O_BOOL))) { operand[2] = operand[0]; operand[0] = gmVariable(GM_NULL, 0); operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); SetTop(operand + 3); // Return to the same instruction after making the call but it will be testing the results of the call. --instruction32; State res = PushStackFrame(1, &instruction, &code); top = GetTop(); base = GetBase(); if(res == RUNNING) break; if(res == SYS_YIELD) return RUNNING; if(res == SYS_EXCEPTION) goto LabelException; if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread return res; } } if(operand->m_value.m_int == 0) { instruction = code + OPCODE_PTR_NI(instruction); } else instruction += sizeof(gmptr); #else // !GM_BOOL_OP --top; if(top->m_value.m_int == 0) { instruction = code + OPCODE_PTR_NI(instruction); } else instruction += sizeof(gmptr); #endif // !GM_BOOL_OP break; } case BC_BRNZ : { #if GM_BOOL_OP operand = top - 1; --top; if (operand->m_type > GM_USER) { // Look for overridden operator. gmOperatorFunction op = OPERATOR(operand->m_type, O_BOOL); if (op) { op(this, operand); } else if ((fn = CALLOPERATOR(operand->m_type, O_BOOL))) { operand[2] = operand[0]; operand[0] = gmVariable(GM_NULL, 0); operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); SetTop(operand + 3); // Return to the same instruction after making the call but it will be testing the results of the call. --instruction32; State res = PushStackFrame(1, &instruction, &code); top = GetTop(); base = GetBase(); if(res == RUNNING) break; if(res == SYS_YIELD) return RUNNING; if(res == SYS_EXCEPTION) goto LabelException; if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread return res; } } if(operand->m_value.m_int != 0) { instruction = code + OPCODE_PTR_NI(instruction); } else instruction += sizeof(gmptr); #else // !GM_BOOL_OP --top; if(top->m_value.m_int != 0) { instruction = code + OPCODE_PTR_NI(instruction); } else instruction += sizeof(gmptr); #endif // !GM_BOOL_OP break; } case BC_BRZK : { #if GM_BOOL_OP operand = top - 1; if (operand->m_type > GM_USER) { // Look for overridden operator. gmOperatorFunction op = OPERATOR(operand->m_type, O_BOOL); if (op) { op(this, operand); } else if ((fn = CALLOPERATOR(operand->m_type, O_BOOL))) { operand[2] = operand[0]; operand[0] = gmVariable(GM_NULL, 0); operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); SetTop(operand + 3); // Return to the same instruction after making the call but it will be testing the results of the call. --instruction32; State res = PushStackFrame(1, &instruction, &code); top = GetTop(); base = GetBase(); if(res == RUNNING) break; if(res == SYS_YIELD) return RUNNING; if(res == SYS_EXCEPTION) goto LabelException; if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread return res; } } if(operand->m_value.m_int == 0) { instruction = code + OPCODE_PTR_NI(instruction); } else instruction += sizeof(gmptr); #else // !GM_BOOL_OP if(top[-1].m_value.m_int == 0) { instruction = code + OPCODE_PTR_NI(instruction); } else instruction += sizeof(gmptr); #endif // !GM_BOOL_OP break; } case BC_BRNZK : { #if GM_BOOL_OP operand = top - 1; if (operand->m_type > GM_USER) { // Look for overridden operator. gmOperatorFunction op = OPERATOR(operand->m_type, O_BOOL); if (op) { op(this, operand); } else if ((fn = CALLOPERATOR(operand->m_type, O_BOOL))) { operand[2] = operand[0]; operand[0] = gmVariable(GM_NULL, 0); operand[1] = gmVariable(GM_FUNCTION, fn->GetRef()); SetTop(operand + 3); // Return to the same instruction after making the call but it will be testing the results of the call. --instruction32; State res = PushStackFrame(1, &instruction, &code); top = GetTop(); base = GetBase(); if(res == RUNNING) break; if(res == SYS_YIELD) return RUNNING; if(res == SYS_EXCEPTION) goto LabelException; if(res == KILLED) { m_machine->Sys_SwitchState(this, KILLED); GM_ASSERT(0); } // operator should not kill a thread return res; } } if(operand->m_value.m_int != 0) { instruction = code + OPCODE_PTR_NI(instruction); } else instruction += sizeof(gmptr); #else // !GM_BOOL_OP if(top[-1].m_value.m_int != 0) { instruction = code + OPCODE_PTR_NI(instruction); } else instruction += sizeof(gmptr); #endif // !GM_BOOL_OP break; } case BC_CALL : { SetTop(top); int numParams = (int) OPCODE_INT(instruction); State res = PushStackFrame(numParams, &instruction, &code); top = GetTop(); base = GetBase(); if(res == RUNNING) { #if GMDEBUG_SUPPORT if(m_debugFlags && m_machine->GetDebugMode() && m_machine->m_call) { m_instruction = instruction; if(m_machine->m_call(this)) return RUNNING; } #endif // GMDEBUG_SUPPORT break; } if(res == SYS_YIELD) return RUNNING; if(res == SYS_EXCEPTION) goto LabelException; if(res == KILLED) { if(a_return) *a_return = m_stack[m_top - 1]; m_machine->Sys_SwitchState(this, KILLED); } return res; } case BC_RET : { PUSHNULL; } case BC_RETV : { SetTop(top); int res = Sys_PopStackFrame(instruction, code); top = GetTop(); base = GetBase(); if(res == RUNNING) { #if GMDEBUG_SUPPORT if(m_debugFlags && m_machine->GetDebugMode() && m_machine->m_return) { m_instruction = instruction; if(m_machine->m_return(this)) return RUNNING; } #endif // GMDEBUG_SUPPORT break; } if(res == KILLED) { if(a_return) *a_return = *(top - 1); m_machine->Sys_SwitchState(this, KILLED); return KILLED; } if(res == SYS_EXCEPTION) goto LabelException; break; } #if GM_USE_FORK // duplicates the current thread and just the local stack frame // and branches around the forked section of code case BC_FORK : { int id; gmThread* newthr = GetMachine()->CreateThread(&id); GM_ASSERT( newthr ); // make sure there is enough room newthr->Touch( m_size - m_base + 2 - GMTHREAD_SLACKSPACE); // copy stack and vars memcpy( newthr->m_stack, &m_stack[ m_base - 2 ], sizeof( gmVariable ) * (m_top - m_base + 2 ) ); newthr->m_top = m_top - m_base + 2; newthr->m_frame = m_machine->Sys_AllocStackFrame(); newthr->m_frame->m_prev = 0; newthr->m_frame->m_returnAddress = 0; newthr->m_frame->m_returnBase = 0; newthr->m_base = 2; newthr->m_instruction = instruction + sizeof(gmptr); // skip branch on other thread newthr->PushInt( GetId() ); instruction = code + OPCODE_PTR_NI( instruction ); // branch top->m_type = GM_INT; top->m_value.m_int = newthr->GetId(); ++top; break; } #endif //GM_USE_FORK case BC_FOREACH : { gmuint32 localvalue = OPCODE_INT(instruction); gmuint32 localkey = localvalue >> 16; localvalue &= 0xffff; // iterator is at tos-1, table is at tos -2, push int 1 if continuing loop. write key and value into localkey and localvalue if(top[-2].m_type != GM_TABLE) { #if GM_USER_FOREACH gmTypeIteratorCallback itrfunc = m_machine->GetUserTypeIteratorCallback(top[-2].m_type); if (!itrfunc) { GMTHREAD_LOG("foreach expression has no iterator function"); goto LabelException; } gmTypeIterator it = (gmTypeIterator) top[-1].m_value.m_int; gmUserObject *obj = (gmUserObject*)GM_MOBJECT(m_machine, top[-2].m_value.m_ref); // Do callback for getnext gmVariable localvar; gmVariable localkeyvar; itrfunc(this, obj, it, &localkeyvar, &localvar); if (it != GM_TYPE_ITR_NULL) { base[localkey] = localkeyvar; base[localvalue] = localvar; top->m_type = GM_INT; top->m_value.m_int = 1; } else { top->m_type = GM_INT; top->m_value.m_int = 0; } top[-1].m_value.m_int = it; ++top; #else //GM_USER_FOREACH (original) GMTHREAD_LOG("foreach expression is not table type"); goto LabelException; #endif //GM_USER_FOREACH } else { GM_ASSERT(top[-1].m_type == GM_INT); gmTableIterator it = (gmTableIterator) top[-1].m_value.m_int; gmTableObject * table = (gmTableObject *) GM_MOBJECT(m_machine, top[-2].m_value.m_ref); gmTableNode * node = table->GetNext(it); top[-1].m_value.m_int = it; if(node) { base[localkey] = node->m_key; base[localvalue] = node->m_value; top->m_type = GM_INT; top->m_value.m_int = 1; } else { top->m_type = GM_INT; top->m_value.m_int = 0; } ++top; } break; } case BC_POP : { --top; break; } case BC_POP2 : { top -= 2; break; } case BC_DUP : { top[0] = top[-1]; ++top; break; } case BC_DUP2 : { top[0] = top[-2]; top[1] = top[-1]; top += 2; break; } case BC_SWAP : { top[0] = top[-1]; top[-1] = top[-2]; top[-2] = top[0]; break; } case BC_PUSHNULL : { PUSHNULL; break; } case BC_PUSHINT : { top->m_type = GM_INT; top->m_value.m_int = OPCODE_INT(instruction); ++top; break; } case BC_PUSHINT0 : { top->m_type = GM_INT; top->m_value.m_int = 0; ++top; break; } case BC_PUSHINT1 : { top->m_type = GM_INT; top->m_value.m_int = 1; ++top; break; } case BC_PUSHFP : { top->m_type = GM_FLOAT; top->m_value.m_float = OPCODE_FLOAT(instruction); ++top; break; } case BC_PUSHSTR : { top->m_type = GM_STRING; top->m_value.m_ref = OPCODE_PTR(instruction); ++top; break; } case BC_PUSHTBL : { SetTop(top); top->m_type = GM_TABLE; top->m_value.m_ref = m_machine->AllocTableObject()->GetRef(); ++top; break; } case BC_PUSHFN : { top->m_type = GM_FUNCTION; top->m_value.m_ref = OPCODE_PTR(instruction); ++top; break; } case BC_PUSHTHIS : { *top = *GetThis(); ++top; break; } case BC_GETLOCAL : { gmuint32 offset = OPCODE_INT(instruction); *(top++) = base[offset]; break; } case BC_SETLOCAL : { gmuint32 offset = OPCODE_INT(instruction); // Write barrier old local objects { gmGarbageCollector* gc = m_machine->GetGC(); if( !gc->IsOff() && base[offset].IsReference() ) { gmObject * object = GM_MOBJECT(m_machine, base[offset].m_value.m_ref); gc->WriteBarrier(object); } } base[offset] = *(--top); break; } case BC_GETGLOBAL : { top->m_type = GM_STRING; top->m_value.m_ref = OPCODE_PTR(instruction); *top = m_machine->GetGlobals()->Get(*top); ++top; break; } case BC_SETGLOBAL : { top->m_type = GM_STRING; top->m_value.m_ref = OPCODE_PTR(instruction); m_machine->GetGlobals()->Set(m_machine, *top, *(top-1)); --top; break; } case BC_GETTHIS : { gmptr member = OPCODE_PTR(instruction); const gmVariable * thisVar = GetThis(); *top = *thisVar; top[1].m_type = GM_STRING; top[1].m_value.m_ref = member; gmOperatorFunction op = OPERATOR(thisVar->m_type, O_GETDOT); if(op) { op(this, top); if(top->m_type) { ++top; break; } } if(thisVar->m_type == GM_NULL) { GMTHREAD_LOG("getthis failed. this is null"); goto LabelException; } *top = m_machine->GetTypeVariable(thisVar->m_type, top[1]); ++top; break; } case BC_SETTHIS : { gmptr member = OPCODE_PTR(instruction); const gmVariable * thisVar = GetThis(); operand = top - 1; *top = *operand; *operand = *thisVar; top[1].m_type = GM_STRING; top[1].m_value.m_ref = member; --top; gmOperatorFunction op = OPERATOR(thisVar->m_type, O_SETDOT); if(op) { op(this, operand); } else { GMTHREAD_LOG("setthis failed."); goto LabelException; } break; } default : { break; } } } LabelException: // // exception handler // m_instruction = instruction; // spit out error info LogLineFile(); LogCallStack(); // call machine exception handler if(gmMachine::s_machineCallback) { if(gmMachine::s_machineCallback(m_machine, MC_THREAD_EXCEPTION, this)) { #if GMDEBUG_SUPPORT // if we are being debugged, put this thread into a limbo state, waiting for delete. if(m_machine->GetDebugMode() && m_machine->m_debugUser) { m_machine->Sys_SwitchState(this, EXCEPTION); return EXCEPTION; } #endif } } // kill the thread m_machine->Sys_SwitchState(this, KILLED); return KILLED; }
BOOL CImage::ObjEditInit(LPOBJECT lpObject, UNDO_TYPE UndoType) { LPALPHA lpAlpha; LPOBJECT lpNext; BOOL fBase, fDataInit, fAlphaInit; LPCOLORMAP lpColorMap; // See if this objects the base, and get alpha channel of object fBase = (lpObject == GetBase()); lpAlpha = lpObject->lpAlpha; // // HANDLE INITIALIZATION OF OBJECT DATA // fDataInit = (UndoType & UT_DATAUNDO) != 0; if (fDataInit && !(Control.NoUndo || fDisableUndos)) { // Apply any changes that have been made if in auto apply mode // or if in manual apply mode and changes have been undone // the init flag is set only if we are doing an edit in place change // to the data so we get rid of any useless undo's if (!Control.UseApply || ( Control.UseApply && !lpObject->DataUndoNotRedo ) ) ObjEditApply(lpObject, YES, !fBase, (UndoType & UT_DATA) != 0); // Save undo information for the specific type of operation if (UndoType & UT_UNDOTEXTDATA && !(lpObject->DataUndoType & UT_UNDOTEXTDATA)) lpObject->lpUndoText = new CTextObject(*lpObject->lpText); if (UndoType & UT_OBJECTRECT && !(lpObject->DataUndoType & UT_OBJECTRECT)) lpObject->rUndoObject = lpObject->rObject; if (UndoType & UT_RESOLUTION && !(lpObject->DataUndoType & UT_RESOLUTION)) lpObject->UndoResolution = FrameResolution(ObjGetEditFrame(lpObject)); if (UndoType & UT_COLORMAP && !(lpObject->DataUndoType & UT_COLORMAP)) { if (lpColorMap = FrameGetColorMap(ObjGetEditFrame(lpObject))) lpObject->UndoColorMap = FrameCopyColorMap(lpColorMap); else lpObject->UndoColorMap = NULL; } if (UndoType & UT_SELECTION && !(lpObject->DataUndoType & UT_SELECTION)) lpObject->fUndoSelected = lpObject->fSelected; // Size base is a special case for the base and base only if (UndoType & UT_DATA) { // init the data pixmap for editing if (!lpObject->Pixmap.UndoFrame) if (!PixmapInitUndo(&lpObject->Pixmap)) return(FALSE); } if (UndoType & UT_NEWDATA) { if (fBase) UndoDataType = DataType; } if (fBase && UndoType & UT_MOVEOBJECTS && !(lpObject->DataUndoType & UT_MOVEOBJECTS)) { lpNext = lpObject; while (lpNext = GetNextObject(lpNext, YES, NO, NO)) { ObjEditApply(lpNext, TRUE, TRUE, FALSE); lpNext->rUndoObject = lpNext->rObject; } } // Delete objects is a special case for the base and base only if (fBase && UndoType & UT_DELETEOBJECTS && !(lpObject->DataUndoType & UT_DELETEOBJECTS)) { lpNext = lpObject; while (lpNext = GetNextObject(lpNext, YES, NO, YES)) lpNext->fUndoDeleted = NO; } if (UndoType & UT_GROUPOBJECTS && !(lpObject->DataUndoType & UT_GROUPOBJECTS)) lpObject->UndoGroupID = lpObject->wGroupID; if (UndoType & UT_LOCKOBJECTS && !(lpObject->DataUndoType & UT_LOCKOBJECTS)) lpObject->bUndoLocked = lpObject->bLocked; } // now that we have successfully initialized everything set UndoTypes if (fDataInit) { lpObject->DataUndoNotRedo = YES; lpObject->DataUndoType |= (UndoType & UT_DATAUNDO); } // // HANDLE INITIALIZATION OF OBJECT ALPHA // fAlphaInit = (UndoType & UT_ALPHAUNDO) != 0; if (fAlphaInit && !(Control.NoUndo || fDisableUndos) && (!fBase || Control.UndoMasks)) { // Apply any changes that have been made if in auto apply mode // or if in manual apply mode and changes have been undone or // apply any changes only to the mask // or if it is a change to both data and mask and // both were not dirty before // Initialize the data undo if the object is not the base and we didn't // already do a data init // the init flag is set only if we are doing an edit in place change // to the alpha so we get rid of any useless undo's if (!Control.UseApply || (Control.UseApply && !lpObject->AlphaUndoNotRedo) || (fBase && (!fDataInit || !lpObject->fBothDirty))) ObjEditApply(lpObject, fDataInit ? NO : !fBase, YES, (UndoType & UT_ALPHA) != 0); // Save undo information for the specific type of operation if (lpAlpha) { if (!lpObject->AlphaUndoType) { if (UndoType & UT_ALPHA) { // init the data pixmap for editing if (!lpAlpha->Pixmap.UndoFrame) if (!PixmapInitUndo(&lpAlpha->Pixmap)) return(FALSE); lpAlpha->rUndoMask = lpAlpha->rMask; } if (UndoType & UT_NEWALPHA) lpAlpha->rUndoMask = lpAlpha->rMask; if (fBase && UndoType & UT_CREATEMASK) lpObject->lpUndoAlpha = NULL; if (fBase && UndoType & UT_DELETEMASK) lpObject->lpUndoAlpha = lpAlpha; if (UndoType & UT_ALPHAUNDO) { lpObject->AlphaUndoNotRedo = YES; lpObject->AlphaUndoType |= (UndoType & UT_ALPHAUNDO); } } } } return(TRUE); }
void CImage::EditUndo( BOOL fEditUndo, BOOL fMaskUndo, LPUPDATE_TYPE lpUpdateType, LPRECT lpUpdateRect) { RECT rUndo, rUndoMask, rTemp; LPOBJECT lpBase, lpObject, lpNext; BOOL fNewSize, fSetupMiniViews, fRemoveMarquee, fUndoDelete, fColorMapChanged; BOOL fUndoAlpha, fUndoData; int nDeleted; LPMASK lpMask; EDIT_TARGET Target; AstralSetRectEmpty(lpUpdateRect); // Initialize things for updating the display fNewSize = fSetupMiniViews = fUndoDelete = fColorMapChanged = NO; AstralSetRectEmpty(&rUndo); AstralSetRectEmpty(&rUndoMask); // loop through objects doing undo lpBase = GetBase(); lpObject = NULL; // get the target of the last edit Target = EditTarget; while (lpObject = GetNextObject(lpObject, NO, NO, fEditUndo)) { // See if this is an object we are undoing if (fEditUndo) { // check for special undo processing of a deleted object if (lpObject->fDeleted) continue; // do no undo processing for a deleted object // { // if (Control.UndoObjects && !IsSelectedObject(lpBase)) // continue; // } else // if target is not the entire image and we are in undo // object mode and the object is not selected then // skip this object if (Target != ET_ALLOBJECTS && Control.UndoObjects && !IsSelectedObject(lpObject)) continue; } // Only handle mask undo for the base object if (fMaskUndo) { if (lpObject != lpBase || lpObject->fBothDirty || !lpObject->AlphaDirty) continue; } fUndoData = fUndoAlpha = NO; // Do preprocess for doing a data undo if (fEditUndo) { if (lpObject->DataDirty) fUndoData = YES; // See if we need to undo the alpha for this object if ((lpObject != lpBase) && lpObject->lpAlpha && lpObject->AlphaDirty) fUndoAlpha = YES; if (!fUndoData && !fUndoAlpha) continue; // check to see and undoing/redoing deleted objects will change // the select state, if so undraw the object marquee if (lpObject == lpBase && lpObject->DataUndoType & UT_DELETEOBJECTS) { fUndoDelete = YES; fRemoveMarquee = NO; nDeleted = 0; lpNext = lpObject; while (lpNext = GetNextObject(lpNext, YES, NO, YES)) { if (lpNext->fUndoDeleted) ++nDeleted; else if (lpNext->fDeleted && lpNext->fSelected) { fRemoveMarquee = YES; break; } } if (GetSelObject(NULL) == lpBase && !fRemoveMarquee) { if (CountObjects() - nDeleted <= 1) fRemoveMarquee = YES; } if (fRemoveMarquee) { GetObjectMarqueeRect(this, &rTemp); AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp); } } } else // fMaskUndo if (!lpObject->AlphaDirty) continue; else fUndoAlpha = YES; // do a preprocess for undoing the mask caused either by // a mask undo or by an edit function that also edits the mask if (((lpObject == lpBase) && fEditUndo && lpObject->fBothDirty) || fMaskUndo) { if ( lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK) ) { // if the undo is going to delete the mask, // we need to undraw the mask if (GetMask()) { GetMaskMarqueeRect(this, &rTemp); AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp); if (GetMaskUpdateRect(YES, NO, &rTemp)) AstralUnionRect(&rUndoMask, &rUndoMask, &rTemp); } // if the undo is going to create the mask, // we need to undraw the object marquees if // not in mask and object marquee mode else { if (!Control.UseMaskAndObjects) { GetObjectMarqueeRect(this, &rTemp); AstralUnionRect(lpUpdateRect, lpUpdateRect, &rTemp); } } } } // Actually do the undo ObjEditUndo(lpObject, fUndoData, fUndoAlpha); // do a postprocess for undoing the mask if ((lpMask = GetMask()) && (((lpObject == lpBase) && fEditUndo && lpObject->fBothDirty) || fMaskUndo)) { // if the undo is going to add the mask, we need to redraw the mask if (lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK) ) { if (GetMaskUpdateRect(YES, NO, &rTemp)) AstralUnionRect(&rUndoMask, &rUndoMask, &rTemp); } else // just redraw the undo area for the mask AstralUnionRect(&rUndoMask, &rUndoMask, &lpMask->Pixmap.UndoRect); } // Setup rectangle for undoing deletion of objects // Handled specially so that moved objects will still undo // and redo properly if (fEditUndo) { if (lpObject == lpBase && lpObject->DataUndoType & UT_DELETEOBJECTS) { lpNext = lpObject; while (lpNext = GetNextObject(lpNext, YES, NO, YES)) { if (lpNext->fDeleted || lpNext->fUndoDeleted) AstralUnionRect(&rUndo, &rUndo, &lpNext->rObject); } fSetupMiniViews = YES; } if (lpObject->DataUndoType & UT_COLORMAP) fColorMapChanged = YES; if (lpObject->Pixmap.fNewFrame) { /* if new frame, cause window to be redisplayed */ if (lpObject == lpBase) fNewSize = YES; else { if (!fNewSize) { AstralUnionRect(&rUndo, &rUndo, &lpObject->rObject); AstralUnionRect(&rUndo, &rUndo, &lpObject->rUndoObject); } } } else { AstralSetRectEmpty(&rTemp); if (fUndoData) AstralUnionRect(&rTemp, &rTemp, &lpObject->Pixmap.UndoRect); if (fUndoAlpha) AstralUnionRect(&rTemp, &rTemp, &lpObject->lpAlpha->Pixmap.UndoRect); if (rTemp.right >= rTemp.left) { if (!fNewSize) { OffsetRect(&rTemp, lpObject->rObject.left, lpObject->rObject.top); AstralUnionRect(&rUndo, &rUndo, &rTemp); } } if( lpObject->DataUndoType & UT_OBJECTRECT ) { AstralUnionRect( &rUndo, &rUndo, &lpObject->rObject ); AstralUnionRect( &rUndo, &rUndo, &lpObject->rUndoObject ); } } } } // now redisplay whatever changes are necessary for the undo if (fColorMapChanged) { ImgColorMapChanged(this); *lpUpdateType |= UT_DATATYPE; } if (fNewSize) { *lpUpdateType |= UT_DATATYPE; if (lpBase->Pixmap.UndoFrame) { if ((FrameXSize(lpBase->Pixmap.UndoFrame) == FrameXSize(lpBase->Pixmap.EditFrame)) && (FrameYSize(lpBase->Pixmap.UndoFrame) == FrameYSize(lpBase->Pixmap.EditFrame))) fNewSize = NO; } if (fNewSize) *lpUpdateType |= UT_SIZE; else { int dx, dy; GetInfo(&dx, &dy, NULL, NULL); SetRect(lpUpdateRect, 0, 0, dx-1, dy-1); } } else { if (!AstralIsRectEmpty(lpUpdateRect)) *lpUpdateType |= UT_ACTIVEAREA; if (rUndoMask.right >= rUndoMask.left) { *lpUpdateType |= UT_ACTIVEAREA; AstralUnionRect(lpUpdateRect, lpUpdateRect, &rUndoMask); } if (rUndo.right >= rUndo.left) { *lpUpdateType |= UT_AREA; AstralUnionRect(lpUpdateRect, lpUpdateRect, &rUndo); } } }
void VehicleKit::Initialize(uint32 creatureEntry) { InstallAllAccessories(creatureEntry ? creatureEntry : GetBase()->GetEntry()); UpdateFreeSeatCount(); m_isInitialized = true; }
VehicleKit::~VehicleKit() { Reset(); GetBase()->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE); }
void VehicleKit::RemovePassenger(Unit* passenger, bool dismount) { SeatMap::iterator seat; for (seat = m_Seats.begin(); seat != m_Seats.end(); ++seat) if (seat->second.passenger == passenger->GetObjectGuid()) break; if (seat == m_Seats.end()) return; seat->second.passenger.Clear(); passenger->clearUnitState(UNIT_STAT_ON_VEHICLE); UnBoardPassenger(passenger); // Use TransportBase to remove the passenger from storage list passenger->m_movementInfo.ClearTransportData(); passenger->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ONTRANSPORT); if (seat->second.IsProtectPassenger()) if (passenger->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) passenger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); if (seat->second.seatInfo->m_flags & SEAT_FLAG_CAN_CONTROL) { passenger->SetCharm(NULL); passenger->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE); GetBase()->SetCharmerGuid(ObjectGuid()); GetBase()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); GetBase()->clearUnitState(UNIT_STAT_CONTROLLED); if (passenger->GetTypeId() == TYPEID_PLAYER) { Player* player = (Player*)passenger; player->SetClientControl(GetBase(), 0); player->RemovePetActionBar(); } if(!(((Creature*)GetBase())->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_KEEP_AI)) ((Creature*)GetBase())->AIM_Initialize(); } if (passenger->GetTypeId() == TYPEID_PLAYER) { Player* player = (Player*)passenger; player->SetViewPoint(NULL); passenger->SetRoot(false); player->SetMover(player); player->m_movementInfo.RemoveMovementFlag(MOVEFLAG_ROOT); if ((GetBase()->HasAuraType(SPELL_AURA_FLY) || GetBase()->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED)) && (!player->HasAuraType(SPELL_AURA_FLY) && !player->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED))) { WorldPacket data; data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12); data << player->GetPackGUID(); data << (uint32)(0); GetBase()->SendMessageToSet(&data,false); player->m_movementInfo.RemoveMovementFlag(MOVEFLAG_FLYING); player->m_movementInfo.RemoveMovementFlag(MOVEFLAG_CAN_FLY); } } UpdateFreeSeatCount(); if (GetBase()->GetTypeId() == TYPEID_UNIT) { if (((Creature*)GetBase())->AI()) ((Creature*)GetBase())->AI()->PassengerBoarded(passenger, seat->first, false); } if (passenger->GetTypeId() == TYPEID_UNIT) { if (((Creature*)passenger)->AI()) ((Creature*)passenger)->AI()->EnteredVehicle(GetBase(), seat->first, false); } if (dismount && seat->second.b_dismount) { Dismount(passenger, seat->second.seatInfo); // only for flyable vehicles if (GetBase()->m_movementInfo.HasMovementFlag(MOVEFLAG_FLYING)) GetBase()->CastSpell(passenger, 45472, true); // Parachute } }
bool CMemoryStack::Init( unsigned maxSize, unsigned commitSize, unsigned initialCommit, unsigned alignment ) { Assert( !m_pBase ); #ifdef _X360 m_bPhysical = false; #endif m_maxSize = maxSize; m_alignment = AlignValue( alignment, 4 ); Assert( m_alignment == alignment ); Assert( m_maxSize > 0 ); #if defined(_WIN32) if ( commitSize != 0 ) { m_commitSize = commitSize; } unsigned pageSize; #ifndef _X360 SYSTEM_INFO sysInfo; GetSystemInfo( &sysInfo ); Assert( !( sysInfo.dwPageSize & (sysInfo.dwPageSize-1)) ); pageSize = sysInfo.dwPageSize; #else pageSize = 64*1024; #endif if ( m_commitSize == 0 ) { m_commitSize = pageSize; } else { m_commitSize = AlignValue( m_commitSize, pageSize ); } m_maxSize = AlignValue( m_maxSize, m_commitSize ); Assert( m_maxSize % pageSize == 0 && m_commitSize % pageSize == 0 && m_commitSize <= m_maxSize ); m_pBase = (unsigned char *)VirtualAlloc( NULL, m_maxSize, VA_RESERVE_FLAGS, PAGE_NOACCESS ); Assert( m_pBase ); m_pCommitLimit = m_pNextAlloc = m_pBase; if ( initialCommit ) { initialCommit = AlignValue( initialCommit, m_commitSize ); Assert( initialCommit < m_maxSize ); if ( !VirtualAlloc( m_pCommitLimit, initialCommit, VA_COMMIT_FLAGS, PAGE_READWRITE ) ) return false; m_minCommit = initialCommit; m_pCommitLimit += initialCommit; MemAlloc_RegisterExternalAllocation( CMemoryStack, GetBase(), GetSize() ); } #else m_pBase = (byte *)MemAlloc_AllocAligned( m_maxSize, alignment ? alignment : 1 ); m_pNextAlloc = m_pBase; m_pCommitLimit = m_pBase + m_maxSize; #endif m_pAllocLimit = m_pBase + m_maxSize; return ( m_pBase != NULL ); }
bool VehicleKit::AddPassenger(Unit *passenger, int8 seatId) { SeatMap::iterator seat; if (seatId < 0) // no specific seat requirement { for (seat = m_Seats.begin(); seat != m_Seats.end(); ++seat) { if (!seat->second.passenger && (seat->second.seatInfo->IsUsable() || (seat->second.seatInfo->m_flags & SEAT_FLAG_UNCONTROLLED))) break; } if (seat == m_Seats.end()) // no available seat return false; } else { seat = m_Seats.find(seatId); if (seat == m_Seats.end()) return false; if (seat->second.passenger) return false; } VehicleSeatEntry const* seatInfo = seat->second.seatInfo; seat->second.passenger = passenger; if (!(seatInfo->m_flags & SEAT_FLAG_FREE_ACTION)) passenger->addUnitState(UNIT_STAT_ON_VEHICLE); m_pBase->SetPhaseMask(passenger->GetPhaseMask(), true); passenger->m_movementInfo.ClearTransportData(); passenger->m_movementInfo.AddMovementFlag(MOVEFLAG_ONTRANSPORT); if (GetBase()->m_movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT)) { passenger->m_movementInfo.SetTransportData(GetBase()->m_movementInfo.GetTransportGuid(), // passenger->m_movementInfo.SetTransportData(GetBase()->GetObjectGuid(), seatInfo->m_attachmentOffsetX + GetBase()->m_movementInfo.GetTransportPos()->x, seatInfo->m_attachmentOffsetY + GetBase()->m_movementInfo.GetTransportPos()->y, seatInfo->m_attachmentOffsetZ + GetBase()->m_movementInfo.GetTransportPos()->z, seatInfo->m_passengerYaw + GetBase()->m_movementInfo.GetTransportPos()->o, WorldTimer::getMSTime(), seat->first, seatInfo); DEBUG_LOG("VehicleKit::AddPassenger passenger %s transport offset on %s setted to %f %f %f %f (parent - %s)", passenger->GetObjectGuid().GetString().c_str(), passenger->m_movementInfo.GetTransportGuid().GetString().c_str(), passenger->m_movementInfo.GetTransportPos()->x, passenger->m_movementInfo.GetTransportPos()->y, passenger->m_movementInfo.GetTransportPos()->z, passenger->m_movementInfo.GetTransportPos()->o, GetBase()->m_movementInfo.GetTransportGuid().GetString().c_str()); } else if (passenger->GetTypeId() == TYPEID_UNIT && b_dstSet) { passenger->m_movementInfo.SetTransportData(m_pBase->GetObjectGuid(), seatInfo->m_attachmentOffsetX + m_dst_x, seatInfo->m_attachmentOffsetY + m_dst_y, seatInfo->m_attachmentOffsetZ + m_dst_z, seatInfo->m_passengerYaw + m_dst_o, WorldTimer::getMSTime(), seat->first, seatInfo); } else { passenger->m_movementInfo.SetTransportData(m_pBase->GetObjectGuid(), seatInfo->m_attachmentOffsetX, seatInfo->m_attachmentOffsetY, seatInfo->m_attachmentOffsetZ, seatInfo->m_passengerYaw, WorldTimer::getMSTime(), seat->first, seatInfo); } if (passenger->GetTypeId() == TYPEID_PLAYER) { ((Player*)passenger)->GetCamera().SetView(m_pBase); WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8+4); data << passenger->GetPackGUID(); data << uint32((passenger->m_movementInfo.GetVehicleSeatFlags() & SEAT_FLAG_CAN_CAST) ? 2 : 0); passenger->SendMessageToSet(&data, true); } if (seat->second.IsProtectPassenger()) { switch (m_pBase->GetEntry()) { case 33651: // VX 001 case 33432: // Leviathan MX case 33118: // Ignis (Ulduar) case 32934: // Kologarn Right Arm (Ulduar) case 30234: // Nexus Lord's Hover Disk (Eye of Eternity, Malygos Encounter) case 30248: // Scion's of Eternity Hover Disk (Eye of Eternity, Malygos Encounter) break; case 28817: default: passenger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); break; } passenger->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT); } if (seatInfo->m_flags & SEAT_FLAG_CAN_CONTROL) { if (!(m_pBase->GetVehicleInfo()->GetEntry()->m_flags & (VEHICLE_FLAG_ACCESSORY))) { m_pBase->StopMoving(); m_pBase->GetMotionMaster()->Clear(); m_pBase->CombatStop(true); } m_pBase->DeleteThreatList(); m_pBase->getHostileRefManager().deleteReferences(); m_pBase->SetCharmerGuid(passenger->GetObjectGuid()); m_pBase->addUnitState(UNIT_STAT_CONTROLLED); passenger->SetCharm(m_pBase); if (m_pBase->HasAuraType(SPELL_AURA_FLY) || m_pBase->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED)) { WorldPacket data; data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12); data << m_pBase->GetPackGUID(); data << (uint32)(0); m_pBase->SendMessageToSet(&data,false); } if (passenger->GetTypeId() == TYPEID_PLAYER) { m_pBase->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); if (CharmInfo* charmInfo = m_pBase->InitCharmInfo(m_pBase)) { charmInfo->SetState(CHARM_STATE_ACTION,ACTIONS_DISABLE); charmInfo->InitVehicleCreateSpells(seat->first); } Player* player = (Player*)passenger; player->SetMover(m_pBase); player->SetClientControl(m_pBase, 1); player->VehicleSpellInitialize(); } if(!(((Creature*)m_pBase)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_KEEP_AI)) ((Creature*)m_pBase)->AIM_Initialize(); if (m_pBase->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE)) { WorldPacket data2(SMSG_FORCE_MOVE_ROOT, 8+4); data2 << m_pBase->GetPackGUID(); data2 << (uint32)(2); m_pBase->SendMessageToSet(&data2,false); } else if (passenger->m_movementInfo.GetMovementFlags() & MOVEFLAG_WALK_MODE) ((Creature*)m_pBase)->SetWalk(true); else ((Creature*)m_pBase)->SetWalk(false); } else if (seatInfo->m_flags & SEAT_FLAG_FREE_ACTION || seatInfo->m_flags & SEAT_FLAG_CAN_ATTACK) { if (passenger->GetTypeId() == TYPEID_PLAYER) { Player* player = (Player*)passenger; player->SetClientControl(m_pBase, 0); } } passenger->SendMonsterMoveTransport(m_pBase, SPLINETYPE_FACINGANGLE, SPLINEFLAG_UNKNOWN5, 0, 0.0f); RelocatePassengers(m_pBase->GetPositionX(), m_pBase->GetPositionY(), m_pBase->GetPositionZ()+0.5f, m_pBase->GetOrientation()); UpdateFreeSeatCount(); if (m_pBase->GetTypeId() == TYPEID_UNIT) { if (((Creature*)m_pBase)->AI()) ((Creature*)m_pBase)->AI()->PassengerBoarded(passenger, seat->first, true); } if (b_dstSet && seatInfo->m_flagsB & VEHICLE_SEAT_FLAG_B_EJECTABLE_FORCED) { uint32 delay = seatInfo->m_exitMaxDuration * IN_MILLISECONDS; m_pBase->AddEvent(new PassengerEjectEvent(seatId,*m_pBase), delay); DEBUG_LOG("Vehicle::AddPassenger eject event for %s added, delay %u",passenger->GetObjectGuid().GetString().c_str(), delay); } return true; }
bool Vehicle::AddPassenger(Unit *unit, int8 seatId) { if (unit->GetVehicle() != this) return false; SeatMap::iterator seat; if (seatId < 0) // no specific seat requirement { for (seat = m_Seats.begin(); seat != m_Seats.end(); ++seat) if (!seat->second.passenger && (seat->second.seatInfo->CanEnterOrExit() || seat->second.seatInfo->IsUsableByOverride())) break; if (seat == m_Seats.end()) // no available seat return false; } else { seat = m_Seats.find(seatId); if (seat == m_Seats.end()) return false; if (seat->second.passenger) { if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), seat->second.passenger)) passenger->ExitVehicle(); else seat->second.passenger = NULL; } ASSERT(!seat->second.passenger); } sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s enter vehicle entry %u id %u dbguid %u seat %d", unit->GetName(), me->GetEntry(), m_vehicleInfo->m_ID, me->GetGUIDLow(), (int32)seat->first); seat->second.passenger = unit->GetGUID(); if (seat->second.seatInfo->CanEnterOrExit()) { ASSERT(m_usableSeatNum); --m_usableSeatNum; if (!m_usableSeatNum) { if (me->GetTypeId() == TYPEID_PLAYER) me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE); else me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); } } if (seat->second.seatInfo->m_flags && !(seat->second.seatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK11)) unit->AddUnitState(UNIT_STAT_ONVEHICLE); unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); VehicleSeatEntry const *veSeat = seat->second.seatInfo; unit->m_movementInfo.t_pos.m_positionX = veSeat->m_attachmentOffsetX; unit->m_movementInfo.t_pos.m_positionY = veSeat->m_attachmentOffsetY; unit->m_movementInfo.t_pos.m_positionZ = veSeat->m_attachmentOffsetZ; unit->m_movementInfo.t_pos.m_orientation = 0; unit->m_movementInfo.t_time = 0; // 1 for player unit->m_movementInfo.t_seat = seat->first; if (me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL) { if (!me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE)) ASSERT(false); // hack: should be done by aura system if (VehicleScalingInfo const *scalingInfo = sObjectMgr->GetVehicleScalingInfo(m_vehicleInfo->m_ID)) { Player *plr = unit->ToPlayer(); float averageItemLevel = plr->GetAverageItemLevel(); if (averageItemLevel < scalingInfo->baseItemLevel) averageItemLevel = scalingInfo->baseItemLevel; averageItemLevel -= scalingInfo->baseItemLevel; float currentHealthPct = float(me->GetHealth() / me->GetMaxHealth()); m_bonusHP = uint32(me->GetMaxHealth() * (averageItemLevel * scalingInfo->scalingFactor)); me->SetMaxHealth(me->GetMaxHealth() + m_bonusHP); me->SetHealth(uint32((me->GetHealth() + m_bonusHP) * currentHealthPct)); } } if (me->IsInWorld()) { unit->SendClearTarget(); // SMSG_BREAK_TARGET unit->SetControlled(true, UNIT_STAT_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures) // also adds MOVEMENTFLAG_ROOT unit->SendMonsterMoveTransport(me); // SMSG_MONSTER_MOVE_TRANSPORT if (me->GetTypeId() == TYPEID_UNIT) { if (me->ToCreature()->IsAIEnabled) me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true); // update all passenger's positions RelocatePassengers(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); } } if (GetBase()->GetTypeId() == TYPEID_UNIT) sScriptMgr->OnAddPassenger(this, unit, seatId); return true; }
BOOL CImage::EditInit( EDIT_TARGET Target, UNDO_TYPE UndoType, LPOBJECT lpTargetObject) { LPOBJECT lpObject, lpBase; int retc; BOOL fDiscardUndo = NO; BOOL fUndoFailed; BOOL fMaskEdit; EDIT_TARGET OldTarget; lpBase = GetBase(); // the InitUndoType flag is kept separately from the // DataUndoType and AlphaUndoType so that if the initialization // of the undo fails we still know what was edited when // EditedObject and EditedObjectFrame are called lpObject = NULL; while (lpObject = GetNextObject(lpObject, YES, NO)) lpObject->InitUndoType = 0; // No mask undo's are allowed - so apply any that we have now if (!Control.UndoMasks) ObjEditApply(lpBase, NO, YES, NO); // No undo's are allowed - so apply any that we have now if (Control.NoUndo || fDisableUndos) { lpObject = NULL; while (lpObject = GetNextObject(lpObject, YES, NO)) ObjEditApply(lpObject, YES, lpObject != lpBase, NO); } // if we have don't have multiple objects, strip off the delete objects flag if (!Control.MultipleObjects) UndoType &= ~UT_DELETEOBJECTS; // find out whether we are in mask edit mode fMaskEdit = (Target == ET_OBJECT) && (lpTargetObject == lpBase) && ((UndoType & UT_ALPHAUNDO) != 0); // see if any objects cannot have their undos freed without // asking the user first, if so ask the user and get the response // This is only a manual apply thing if (UndoType & (UT_NEWDATA|UT_NEWALPHA) && Control.UseApply) { lpObject = NULL; fDiscardUndo = YES; while (lpObject = GetNextObject(lpObject, YES, NO)) { // see if this is an object we are not editing if ((Target == ET_SELOBJECTS && !IsSelectedObject(lpObject)) || (Target == ET_OBJECT && lpObject != lpTargetObject)) continue; if (!ObjEditUndoDiscardable(lpObject, (UndoType & UT_NEWDATA) != 0, (UndoType & UT_NEWALPHA) != 0)) { if (lpCmdList->fPlayback) { fDiscardUndo = fDiscardUndo; } else { DISCARDUNDO_PARMS parms; retc = AstralConfirm( IDS_OKTOAPPLY ); if (retc == IDCANCEL) return(FALSE); fDiscardUndo = retc == IDYES; parms.fDiscardUndo = fDiscardUndo; PostCommand(lpCmdList, IDS_CMD_DISCARDUNDO, &parms); } break; } } } OldTarget = EditTarget; EditTarget = Target; // now loop through the objects initializing their undos lpObject = NULL; while (lpObject = GetNextObject(lpObject, YES, NO)) { // if our last edit involved editing all objects then // make sure we apply for all objects if (OldTarget == ET_ALLOBJECTS) { ObjEditApply(lpObject, !fMaskEdit, (lpObject != lpBase) && !fMaskEdit, NO); } // see if this is an object we are not editing if ((Target == ET_SELOBJECTS && !IsSelectedObject(lpObject)) || (Target == ET_OBJECT && lpObject != lpTargetObject)) { // if no individual undo's, wack any undo buffers // if in auto apply or in manual apply and state is redo // Objects that are not the base need to also have // their alphas wacked if this is not a mask edit if (!Control.UndoObjects && (!Control.UseApply || ( Control.UseApply && !lpObject->DataUndoNotRedo ) ) ) ObjEditApply(lpObject, !fMaskEdit, (lpObject != lpBase) && !fMaskEdit, NO); continue; } // Discard it's undo if possible if (fDiscardUndo) ObjEditFreeUndo(lpObject, (UndoType & UT_NEWDATA) != 0, (UndoType & UT_NEWALPHA) != 0); // save state of undo failed flag fUndoFailed = lpObject->fUndoFailed; // Initialize the undo for this object if (!ObjEditInit(lpObject, UndoType)) { // Undo initialization failed, so apply all objects that // were going to be initialized lpObject = NULL; while (lpObject = GetNextObject(lpObject, YES, NO)) { // see if this is an object we are not editing if ((Target == ET_SELOBJECTS && !IsSelectedObject(lpObject)) || (Target == ET_OBJECT && lpObject != lpTargetObject)) { continue; } lpObject->fUndoFailed = YES; lpObject->InitUndoType = 0; if (lpObject == lpBase) ObjEditApply(lpObject, (UndoType & UT_DATAUNDO) != 0, (UndoType & UT_ALPHAUNDO) != 0, NO); else ObjEditApply(lpObject, YES, YES, NO); } // if we have failed before if (fUndoFailed) return(TRUE); else { Message(IDS_NOUNDO); return(FALSE); } } lpObject->fUndoFailed = NO; lpObject->InitUndoType = UndoType; } return( TRUE ); }
void CImage::ObjEditApply(LPOBJECT lpObject, BOOL fApplyData, BOOL fApplyAlpha, BOOL fInitFrame) { LPALPHA lpAlpha; LPOBJECT lpNext; BOOL fInitingData, fInitingAlpha; if (!fApplyData && !fApplyAlpha) return; lpObject->InitUndoType = 0; fInitingAlpha = fInitFrame && fApplyAlpha; fInitingData = fInitFrame && fApplyData; lpAlpha = lpObject->lpAlpha; if (fApplyData) { if (lpObject->fBothDirty) fApplyAlpha = YES; if (lpObject == GetBase()) { PurgeObjects(); lpNext = lpObject; while (lpNext = GetNextObject(lpNext, YES, NO, NO)) lpNext->fUndoDeleted = NO; } if (!fInitingData) PixmapFreeUndo(&lpObject->Pixmap); else PixmapEditApply(&lpObject->Pixmap); if (lpObject->lpUndoText) { delete lpObject->lpUndoText; lpObject->lpUndoText = NULL; } if (lpObject->UndoColorMap) { FrameDestroyColorMap(lpObject->UndoColorMap); lpObject->UndoColorMap = NULL; } lpObject->DataUndoType = 0; lpObject->DataDirty = NO; } if (fApplyAlpha) { if (lpObject->lpUndoAlpha) { MaskClose(lpObject->lpUndoAlpha); lpObject->lpUndoAlpha = NULL; } if (lpAlpha) { if (!fInitingAlpha) PixmapFreeUndo(&lpAlpha->Pixmap); else PixmapEditApply(&lpAlpha->Pixmap); } lpObject->AlphaUndoType = 0; lpObject->AlphaDirty = NO; } lpObject->fBothDirty = NO; }
void CImage::ObjEditUndo(LPOBJECT lpObject, BOOL fUndoData, BOOL fUndoAlpha) { RECT rTemp; BOOL fSelected, Resolution, fDeleted, fBase, bLocked; LPALPHA lpAlpha, lpTemp; LPOBJECT lpNext; int XSize, YSize; int tempDataType; LPCOLORMAP lpColorMap; int GroupID; lpAlpha = lpObject->lpAlpha; fBase = lpObject == GetBase(); if (fUndoData && lpObject->DataDirty) { if (lpObject->DataUndoType & UT_RESOLUTION) Resolution = FrameResolution(lpObject->Pixmap.EditFrame); if (lpObject->DataUndoType & UT_COLORMAP) { if (lpColorMap = FrameGetColorMap(ObjGetEditFrame(lpObject))) lpColorMap = FrameCopyColorMap(lpColorMap); else lpColorMap = NULL; } if (lpObject->DataUndoType & (UT_DATA|UT_NEWDATA)) { PixmapEditUndo(&lpObject->Pixmap); if (fBase) { npix = FrameXSize(ObjGetEditFrame(lpObject)); nlin = FrameYSize(ObjGetEditFrame(lpObject)); if (lpObject->DataUndoType & UT_NEWDATA) { tempDataType = DataType; DataType = UndoDataType; UndoDataType = tempDataType; } } } if (lpObject->DataUndoType & UT_OBJECTRECT) { rTemp = lpObject->rObject; lpObject->rObject = lpObject->rUndoObject; lpObject->rUndoObject = rTemp; } if (lpObject->DataUndoType & UT_RESOLUTION) { FrameSetResolution( lpObject->Pixmap.EditFrame, lpObject->UndoResolution); lpObject->UndoResolution = Resolution; } if (lpObject->DataUndoType & UT_UNDOTEXTDATA) { if (lpObject->lpUndoText) { CTextObject *pTmp = lpObject->lpUndoText; lpObject->lpUndoText = lpObject->lpText; lpObject->lpText = pTmp; } } if (lpObject->DataUndoType & UT_COLORMAP) { if (lpObject->UndoColorMap) { FrameSetColorMap( ObjGetEditFrame(lpObject), lpObject->UndoColorMap); FrameDestroyColorMap(lpObject->UndoColorMap); } lpObject->UndoColorMap = lpColorMap; } if (lpObject->DataUndoType & UT_SELECTION) { fSelected = lpObject->fSelected; lpObject->fSelected = lpObject->fUndoSelected; lpObject->fUndoSelected = fSelected; } if (lpObject->DataUndoType & UT_LOCKOBJECTS) { bLocked = lpObject->bLocked; lpObject->bLocked = lpObject->bUndoLocked; lpObject->bUndoLocked = bLocked; } if (lpObject->DataUndoType & UT_GROUPOBJECTS) { GroupID = lpObject->wGroupID; lpObject->wGroupID = lpObject->UndoGroupID; lpObject->UndoGroupID = GroupID; } if (lpObject->DataUndoType & UT_DELETEOBJECTS) { lpNext = lpObject; while (lpNext = GetNextObject(lpNext, YES, NO, YES)) { if (lpNext->fUndoDeleted || lpNext->fDeleted) { fDeleted = lpNext->fDeleted; lpNext->fDeleted = lpNext->fUndoDeleted; lpNext->fUndoDeleted = fDeleted; } } } if (fBase && lpObject->DataUndoType & UT_MOVEOBJECTS) { lpNext = lpObject; while (lpNext = GetNextObject(lpNext, YES, NO, NO)) { rTemp = lpNext->rObject; lpNext->rObject = lpNext->rUndoObject; lpNext->rUndoObject = rTemp; } } lpObject->DataUndoNotRedo = !lpObject->DataUndoNotRedo; if (!fUndoAlpha) fUndoAlpha = lpObject->fBothDirty; } else if (fUndoAlpha && lpObject->fBothDirty) fUndoAlpha = NO; if (fUndoAlpha && lpObject->AlphaDirty) { if (lpAlpha) { if (lpObject->AlphaUndoType & (UT_ALPHA|UT_NEWALPHA)) { PixmapEditUndo(&lpAlpha->Pixmap); rTemp = lpAlpha->rMask; lpAlpha->rMask = lpAlpha->rUndoMask; lpAlpha->rUndoMask = rTemp; } } if (lpObject->AlphaUndoType & (UT_CREATEMASK|UT_DELETEMASK)) { lpTemp = lpObject->lpAlpha; lpObject->lpAlpha = lpObject->lpUndoAlpha; lpObject->lpUndoAlpha = lpTemp; } lpObject->AlphaUndoNotRedo = !lpObject->AlphaUndoNotRedo; } lpAlpha = lpObject->lpAlpha; // check to make sure the mask is still the same size if (fUndoData && fBase && lpObject->Pixmap.fNewFrame) { // we just undid to a different size frame bag mask delete undo if (lpObject->lpUndoAlpha && !lpObject->fBothDirty) ObjEditApply(lpObject, NO, YES, NO); if (lpAlpha) { XSize = FrameXSize(lpAlpha->Pixmap.EditFrame); YSize = FrameYSize(lpAlpha->Pixmap.EditFrame); if (XSize != FrameXSize(lpObject->Pixmap.EditFrame) || YSize != FrameYSize(lpObject->Pixmap.EditFrame)) { ObjEditInit(lpObject, UT_DELETEMASK); // dont free mask if it was stored for later undo/redo if (!lpObject->lpUndoAlpha) MaskClose(lpObject->lpAlpha); lpObject->fBothDirty = YES; lpObject->AlphaDirty = lpObject->DataDirty; lpObject->lpAlpha = NULL; } } } }
uint16 GetMagicEvasion(CMobEntity* PMob) { uint8 mEvaRank = 3; return GetBase(PMob, mEvaRank); }
void CalculateStats(CMobEntity * PMob) { // remove all to keep mods in sync PMob->StatusEffectContainer->KillAllStatusEffect(); PMob->restoreModifiers(); PMob->restoreMobModifiers(); bool isNM = PMob->m_Type & MOBTYPE_NOTORIOUS; JOBTYPE mJob = PMob->GetMJob(); JOBTYPE sJob = PMob->GetSJob(); uint8 mLvl = PMob->GetMLevel(); ZONETYPE zoneType = PMob->loc.zone->GetType(); if(PMob->HPmodifier == 0) { float hpScale = PMob->HPscale; if (PMob->getMobMod(MOBMOD_HP_SCALE) != 0) { hpScale = (float)PMob->getMobMod(MOBMOD_HP_SCALE) / 100.0f; } float growth = 1.06f; float petGrowth = 0.75f; float base = 18.0f; //give hp boost every 10 levels after 25 //special boosts at 25 and 50 if(mLvl > 75) { growth = 1.28f; petGrowth = 1.03f; } else if(mLvl > 65) { growth = 1.27f; petGrowth = 1.02f; } else if(mLvl > 55) { growth = 1.25f; petGrowth = 0.99f; } else if(mLvl > 50) { growth = 1.21f; petGrowth = 0.96f; } else if(mLvl > 45) { growth = 1.17f; petGrowth = 0.95f; } else if(mLvl > 35) { growth = 1.14f; petGrowth = 0.92f; } else if(mLvl > 25) { growth = 1.1f; petGrowth = 0.82f; } // pets have lower health if(PMob->PMaster != nullptr) { growth = petGrowth; } PMob->health.maxhp = (int16)(base * pow(mLvl, growth) * hpScale); if(isNM) { PMob->health.maxhp = (int32)(PMob->health.maxhp * 2.0f); if(mLvl > 75){ PMob->health.maxhp = (int32)(PMob->health.maxhp * 2.5f); } } } else { PMob->health.maxhp = PMob->HPmodifier; } if(isNM) { PMob->health.maxhp = (int32)(PMob->health.maxhp * map_config.nm_hp_multiplier); } else { PMob->health.maxhp = (int32)(PMob->health.maxhp * map_config.mob_hp_multiplier); } bool hasMp = false; switch(mJob){ case JOB_PLD: case JOB_WHM: case JOB_BLM: case JOB_RDM: case JOB_DRK: case JOB_BLU: case JOB_SCH: case JOB_SMN: hasMp = true; break; default: break; } switch(sJob){ case JOB_PLD: case JOB_WHM: case JOB_BLM: case JOB_RDM: case JOB_DRK: case JOB_BLU: case JOB_SCH: case JOB_SMN: hasMp = true; break; default: break; } if(PMob->getMobMod(MOBMOD_MP_BASE)) { hasMp = true; } if(hasMp) { float scale = PMob->MPscale; if(PMob->getMobMod(MOBMOD_MP_BASE)) { scale = (float)PMob->getMobMod(MOBMOD_MP_BASE) / 100.0f; } if(PMob->MPmodifier == 0) { PMob->health.maxmp = (int16)(18.2 * pow(mLvl,1.1075) * scale) + 10; if(isNM) { PMob->health.maxmp = (int32)(PMob->health.maxmp * 1.5f); if(mLvl>75) { PMob->health.maxmp = (int32)(PMob->health.maxmp * 1.5f); } } } else { PMob->health.maxmp = PMob->MPmodifier; } if(isNM) { PMob->health.maxmp = (int32)(PMob->health.maxmp * map_config.nm_mp_multiplier); } else { PMob->health.maxmp = (int32)(PMob->health.maxmp * map_config.mob_mp_multiplier); } } PMob->UpdateHealth(); PMob->health.tp = 0; PMob->health.hp = PMob->GetMaxHP(); PMob->health.mp = PMob->GetMaxMP(); PMob->m_Weapons[SLOT_MAIN]->setDamage(GetWeaponDamage(PMob)); //reduce weapon delay of MNK if(PMob->GetMJob()==JOB_MNK){ PMob->m_Weapons[SLOT_MAIN]->resetDelay(); } uint16 fSTR = GetBaseToRank(PMob->strRank, mLvl); uint16 fDEX = GetBaseToRank(PMob->dexRank, mLvl); uint16 fVIT = GetBaseToRank(PMob->vitRank, mLvl); uint16 fAGI = GetBaseToRank(PMob->agiRank, mLvl); uint16 fINT = GetBaseToRank(PMob->intRank, mLvl); uint16 fMND = GetBaseToRank(PMob->mndRank, mLvl); uint16 fCHR = GetBaseToRank(PMob->chrRank, mLvl); uint16 mSTR = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),2), mLvl); uint16 mDEX = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),3), mLvl); uint16 mVIT = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),4), mLvl); uint16 mAGI = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),5), mLvl); uint16 mINT = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),6), mLvl); uint16 mMND = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),7), mLvl); uint16 mCHR = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),8), mLvl); uint16 sSTR = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),2), PMob->GetSLevel()); uint16 sDEX = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),3), PMob->GetSLevel()); uint16 sVIT = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),4), PMob->GetSLevel()); uint16 sAGI = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),5), PMob->GetSLevel()); uint16 sINT = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),6), PMob->GetSLevel()); uint16 sMND = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),7), PMob->GetSLevel()); uint16 sCHR = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),8), PMob->GetSLevel()); if(PMob->GetSLevel() > 15) { sSTR /= 2; sDEX /= 2; sAGI /= 2; sINT /= 2; sMND /= 2; sCHR /= 2; sVIT /= 2; } else { sSTR = 0; sDEX = 0; sAGI = 0; sINT = 0; sMND = 0; sCHR = 0; sVIT = 0; } PMob->stats.STR = fSTR + mSTR + sSTR; PMob->stats.DEX = fDEX + mDEX + sDEX; PMob->stats.VIT = fVIT + mVIT + sVIT; PMob->stats.AGI = fAGI + mAGI + sAGI; PMob->stats.INT = fINT + mINT + sINT; PMob->stats.MND = fMND + mMND + sMND; PMob->stats.CHR = fCHR + mCHR + sCHR; if(isNM) { PMob->stats.STR = (uint16)(PMob->stats.STR * 1.5f * map_config.nm_stat_multiplier); PMob->stats.DEX = (uint16)(PMob->stats.DEX * 1.5f * map_config.nm_stat_multiplier); PMob->stats.VIT = (uint16)(PMob->stats.VIT * 1.5f * map_config.nm_stat_multiplier); PMob->stats.AGI = (uint16)(PMob->stats.AGI * 1.5f * map_config.nm_stat_multiplier); PMob->stats.INT = (uint16)(PMob->stats.INT * 1.5f * map_config.nm_stat_multiplier); PMob->stats.MND = (uint16)(PMob->stats.MND * 1.5f * map_config.nm_stat_multiplier); PMob->stats.CHR = (uint16)(PMob->stats.CHR * 1.5f * map_config.nm_stat_multiplier); } else { PMob->stats.STR = (uint16)(PMob->stats.STR * map_config.mob_stat_multiplier); PMob->stats.DEX = (uint16)(PMob->stats.DEX * map_config.mob_stat_multiplier); PMob->stats.VIT = (uint16)(PMob->stats.VIT * map_config.mob_stat_multiplier); PMob->stats.AGI = (uint16)(PMob->stats.AGI * map_config.mob_stat_multiplier); PMob->stats.INT = (uint16)(PMob->stats.INT * map_config.mob_stat_multiplier); PMob->stats.MND = (uint16)(PMob->stats.MND * map_config.mob_stat_multiplier); PMob->stats.CHR = (uint16)(PMob->stats.CHR * map_config.mob_stat_multiplier); } // special case, give spell list to my pet if(PMob->getMobMod(MOBMOD_PET_SPELL_LIST) && PMob->PPet != nullptr) { // Stubborn_Dredvodd CMobEntity* PPet = (CMobEntity*)PMob->PPet; // give pet spell list PPet->m_SpellListContainer = mobSpellList::GetMobSpellList(PMob->getMobMod(MOBMOD_PET_SPELL_LIST)); } if(PMob->getMobMod(MOBMOD_SPELL_LIST)) { PMob->m_SpellListContainer = mobSpellList::GetMobSpellList(PMob->getMobMod(MOBMOD_SPELL_LIST)); } // cap all stats for mLvl / job for (int i=SKILL_DIV; i <=SKILL_BLU; i++) { uint16 maxSkill = battleutils::GetMaxSkill((SKILLTYPE)i,PMob->GetMJob(),mLvl > 99 ? 99 : mLvl); if (maxSkill != 0) { PMob->WorkingSkills.skill[i] = maxSkill; } else //if the mob is WAR/BLM and can cast spell { // set skill as high as main level, so their spells won't get resisted uint16 maxSubSkill = battleutils::GetMaxSkill((SKILLTYPE)i,PMob->GetSJob(),mLvl > 99 ? 99 : mLvl); if (maxSubSkill != 0) { PMob->WorkingSkills.skill[i] = maxSubSkill; } } } for (int i=SKILL_H2H; i <=SKILL_STF; i++) { uint16 maxSkill = battleutils::GetMaxSkill(3, mLvl > 99 ? 99 : mLvl); if (maxSkill != 0) { PMob->WorkingSkills.skill[i] = maxSkill; } } PMob->addModifier(Mod::DEF, GetBase(PMob,PMob->defRank)); PMob->addModifier(Mod::EVA, GetEvasion(PMob)); PMob->addModifier(Mod::ATT, GetBase(PMob,PMob->attRank)); PMob->addModifier(Mod::ACC, GetBase(PMob,PMob->accRank)); //natural magic evasion PMob->addModifier(Mod::MEVA, GetMagicEvasion(PMob)); // add traits for sub and main battleutils::AddTraits(PMob, traits::GetTraits(mJob), mLvl); battleutils::AddTraits(PMob, traits::GetTraits(PMob->GetSJob()), PMob->GetSLevel()); SetupJob(PMob); SetupRoaming(PMob); // All beastmen drop gil if (PMob->m_EcoSystem == SYSTEM_BEASTMEN) { PMob->defaultMobMod(MOBMOD_GIL_BONUS, 100); } if (PMob->PMaster != nullptr) { SetupPetSkills(PMob); } PMob->m_Behaviour |= PMob->getMobMod(MOBMOD_BEHAVIOR); if(zoneType == ZONETYPE_DUNGEON) { SetupDungeonMob(PMob); } else if(zoneType == ZONETYPE_BATTLEFIELD) { SetupBattlefieldMob(PMob); } else if(zoneType == ZONETYPE_DYNAMIS) { SetupDynamisMob(PMob); } if(PMob->m_Type & MOBTYPE_NOTORIOUS) { SetupNMMob(PMob); } if(PMob->m_Type & MOBTYPE_EVENT) { SetupEventMob(PMob); } if(PMob->m_Family == 335) { SetupMaat(PMob); } if (PMob->CanStealGil()) { PMob->ResetGilPurse(); } if(PMob->m_Type & MOBTYPE_EVENT || PMob->m_Type & MOBTYPE_FISHED || PMob->m_Type & MOBTYPE_BATTLEFIELD || zoneType == ZONETYPE_BATTLEFIELD || zoneType == ZONETYPE_DYNAMIS) { PMob->setMobMod(MOBMOD_CHARMABLE, 0); } // Check for possible miss-setups if (PMob->getMobMod(MOBMOD_SPECIAL_SKILL) != 0 && PMob->getMobMod(MOBMOD_SPECIAL_COOL) == 0) { ShowError("Mobutils::CalculateStats Mob (%s, %d) with special skill but no cool down set!\n", PMob->GetName(), PMob->id); } if (PMob->SpellContainer->HasSpells() && PMob->getMobMod(MOBMOD_MAGIC_COOL) == 0) { ShowError("Mobutils::CalculateStats Mob (%s, %d) with magic but no cool down set!\n", PMob->GetName(), PMob->id); } if (PMob->m_Detects == 0) { ShowError("Mobutils::CalculateStats Mob (%s, %d, %d) has no detection methods!\n", PMob->GetName(), PMob->id, PMob->m_Family); } }
void CAOPNormal::UpdateOnRemove(void) { BaseClass::UpdateOnRemove(); pAdminOP.UnhookEnt(GetBase(), this, GetIndex()); }
bool Vehicle::AddPassenger(Unit* unit, int8 seatId) { if(unit->GetVehicle() != this) return false; SeatMap::iterator seat; if(seatId < 0) // no specific seat requirement { for(seat = Seats.begin(); seat != Seats.end(); ++seat) if(!seat->second.Passenger && (seat->second.SeatInfo->CanEnterOrExit() || seat->second.SeatInfo->IsUsableByOverride())) break; if(seat == Seats.end()) // no available seat return false; } else { seat = Seats.find(seatId); if(seat == Seats.end()) return false; if(seat->second.Passenger) { if(Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger)) passenger->ExitVehicle(); else seat->second.Passenger = 0; } ASSERT(!seat->second.Passenger); } sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s enter vehicle entry %u id %u dbguid %u seat %d", unit->GetName(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUIDLow(), (int32)seat->first); seat->second.Passenger = unit->GetGUID(); if(seat->second.SeatInfo->CanEnterOrExit()) { ASSERT(_usableSeatNum); --_usableSeatNum; if(!_usableSeatNum) { if(_me->GetTypeId() == TYPEID_PLAYER) _me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE); else _me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); } } if(seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK11)) unit->AddUnitState(UNIT_STAT_ONVEHICLE); unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); VehicleSeatEntry const* veSeat = seat->second.SeatInfo; unit->m_movementInfo.t_pos.m_positionX = veSeat->m_attachmentOffsetX; unit->m_movementInfo.t_pos.m_positionY = veSeat->m_attachmentOffsetY; unit->m_movementInfo.t_pos.m_positionZ = veSeat->m_attachmentOffsetZ; unit->m_movementInfo.t_pos.m_orientation = 0; unit->m_movementInfo.t_time = 0; // 1 for player unit->m_movementInfo.t_seat = seat->first; if(_me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL) { if(!_me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE)) ASSERT(false); } if(_me->IsInWorld()) { unit->SendClearTarget(); // SMSG_BREAK_TARGET unit->SetControlled(true, UNIT_STAT_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures) // also adds MOVEMENTFLAG_ROOT unit->SendMonsterMoveTransport(_me); // SMSG_MONSTER_MOVE_TRANSPORT if(_me->GetTypeId() == TYPEID_UNIT) { if(_me->ToCreature()->IsAIEnabled) _me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true); // update all passenger's positions RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation()); } } if(GetBase()->GetTypeId() == TYPEID_UNIT) sScriptMgr->OnAddPassenger(this, unit, seatId); return true; }
void CalculateStats(CMobEntity * PMob) { // remove all to keep mods in sync PMob->StatusEffectContainer->KillAllStatusEffect(); PMob->restoreModifiers(); PMob->restoreMobModifiers(); // set a random job if(PMob->getMobMod(MOBMOD_RAND_JOB)) { bool firstOption = WELL512::irand()%2 == 0; SKILLTYPE meleeSkill = SKILL_NON; JOBTYPE job = JOB_NON; uint16 spellList = 0; // skeleton if(PMob->m_Family == 227) { if(firstOption) { // blm job = JOB_BLM; // taken from mob_pools modelid int8 look[23] = {0x00, 0x00, 0x34, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; memcpy(&PMob->look, look, 23); spellList = 28; // undead spell list meleeSkill = SKILL_SYH; } else { // war job = JOB_WAR; int8 look[23] = {0x00, 0x00, 0x3C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; memcpy(&PMob->look, look, 23); meleeSkill = SKILL_AXE; } } // evil weapon else if(PMob->m_Family == 110 || PMob->m_Family == 111) { if(firstOption) { // rdm job = JOB_RDM; meleeSkill = SKILL_SWD; spellList = 42; // evil weapon spell list } else { // war job = JOB_WAR; meleeSkill = SKILL_AXE; } } else { ShowError("mobutils::CalculateStats Undefined family is being set as a random job %d\n", PMob->m_Family); } PMob->SetMJob(job); PMob->SetSJob(job); PMob->m_SpellListContainer = mobSpellList::GetMobSpellList(spellList); PMob->m_Weapons[SLOT_MAIN]->setSkillType(meleeSkill); } bool isNM = PMob->m_Type & MOBTYPE_NOTORIOUS; JOBTYPE mJob = PMob->GetMJob(); JOBTYPE sJob = PMob->GetSJob(); uint8 mLvl = PMob->GetMLevel(); ZONETYPE zoneType = PMob->loc.zone->GetType(); // event mob types will always have custom roaming if(PMob->m_Type & MOBTYPE_EVENT) { PMob->m_roamFlags |= ROAMFLAG_EVENT; PMob->m_maxRoamDistance = 0.2f; // always go back to spawn } if(isNM) { // enmity range is larger PMob->m_enmityRange = 28; } if(mJob == JOB_DRG) { // drg can use 2 hour multiple times PMob->setMobMod(MOBMOD_2HOUR_MULTI, 1); } if(PMob->HPmodifier == 0){ float growth = 1.06; float base = 18.0; uint8 lvl = PMob->GetMLevel(); //give hp boost every 10 levels after 25 //special boosts at 25 and 50 if(lvl > 75){ growth = 1.28; }else if(lvl > 65){ growth = 1.27; } else if(lvl > 55){ growth = 1.25; } else if(lvl > 50){ growth = 1.21; } else if(lvl > 45){ growth = 1.17; } else if(lvl > 35){ growth = 1.14; } else if(lvl > 25){ growth = 1.1; } // pets have lower health if(PMob->PMaster != NULL) { growth = 0.95; } PMob->health.maxhp = (int16)(base * pow(lvl, growth) * PMob->HPscale); if(isNM) { PMob->health.maxhp *= 2.0; if(PMob->GetMLevel() > 75){ PMob->health.maxhp *= 2.5; } } } else { PMob->health.maxhp = PMob->HPmodifier; } bool hasMp = false; switch(mJob){ case JOB_PLD: case JOB_WHM: case JOB_BLM: case JOB_RDM: case JOB_DRK: case JOB_BLU: case JOB_SCH: case JOB_SMN: hasMp = true; break; } switch(sJob){ case JOB_PLD: case JOB_WHM: case JOB_BLM: case JOB_RDM: case JOB_DRK: case JOB_BLU: case JOB_SCH: case JOB_SMN: hasMp = true; break; } if(PMob->getMobMod(MOBMOD_MP_BASE)) { hasMp = true; } if(hasMp) { float scale = PMob->MPscale; if(PMob->getMobMod(MOBMOD_MP_BASE)) { scale = (float)PMob->getMobMod(MOBMOD_MP_BASE) / 100.0f; } if(PMob->MPmodifier == 0){ PMob->health.maxmp = (int16)(18.2 * pow(PMob->GetMLevel(),1.1075) * scale) + 10; if(isNM){ PMob->health.maxmp *= 1.5; if(PMob->GetMLevel()>75){ PMob->health.maxmp *= 1.5; } } } else { PMob->health.maxmp = PMob->MPmodifier; } } PMob->UpdateHealth(); PMob->health.tp = 0; PMob->health.hp = PMob->GetMaxHP(); PMob->health.mp = PMob->GetMaxMP(); PMob->m_Weapons[SLOT_MAIN]->setDamage(GetWeaponDamage(PMob)); //reduce weapon delay of MNK if(PMob->GetMJob()==JOB_MNK){ PMob->m_Weapons[SLOT_MAIN]->resetDelay(); } uint16 fSTR = GetBaseToRank(PMob->strRank, PMob->GetMLevel()); uint16 fDEX = GetBaseToRank(PMob->dexRank, PMob->GetMLevel()); uint16 fVIT = GetBaseToRank(PMob->vitRank, PMob->GetMLevel()); uint16 fAGI = GetBaseToRank(PMob->agiRank, PMob->GetMLevel()); uint16 fINT = GetBaseToRank(PMob->intRank, PMob->GetMLevel()); uint16 fMND = GetBaseToRank(PMob->mndRank, PMob->GetMLevel()); uint16 fCHR = GetBaseToRank(PMob->chrRank, PMob->GetMLevel()); uint16 mSTR = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),2), PMob->GetMLevel()); uint16 mDEX = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),3), PMob->GetMLevel()); uint16 mVIT = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),4), PMob->GetMLevel()); uint16 mAGI = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),5), PMob->GetMLevel()); uint16 mINT = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),6), PMob->GetMLevel()); uint16 mMND = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),7), PMob->GetMLevel()); uint16 mCHR = GetBaseToRank(grade::GetJobGrade(PMob->GetMJob(),8), PMob->GetMLevel()); uint16 sSTR = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),2), PMob->GetSLevel()); uint16 sDEX = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),3), PMob->GetSLevel()); uint16 sVIT = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),4), PMob->GetSLevel()); uint16 sAGI = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),5), PMob->GetSLevel()); uint16 sINT = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),6), PMob->GetSLevel()); uint16 sMND = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),7), PMob->GetSLevel()); uint16 sCHR = GetBaseToRank(grade::GetJobGrade(PMob->GetSJob(),8), PMob->GetSLevel()); if(PMob->GetSLevel() > 15) { sSTR /= 2; sDEX /= 2; sAGI /= 2; sINT /= 2; sMND /= 2; sCHR /= 2; sVIT /= 2; } else { sSTR = 0; sDEX = 0; sAGI = 0; sINT = 0; sMND = 0; sCHR = 0; sVIT = 0; } PMob->stats.STR = fSTR + mSTR + sSTR; PMob->stats.DEX = fDEX + mDEX + sDEX; PMob->stats.VIT = fVIT + mVIT + sVIT; PMob->stats.AGI = fAGI + mAGI + sAGI; PMob->stats.INT = fINT + mINT + sINT; PMob->stats.MND = fMND + mMND + sMND; PMob->stats.CHR = fCHR + mCHR + sCHR; if(isNM){ PMob->stats.STR *= 1.5; PMob->stats.DEX *= 1.5; PMob->stats.VIT *= 1.5; PMob->stats.AGI *= 1.5; PMob->stats.INT *= 1.5; PMob->stats.MND *= 1.5; PMob->stats.CHR *= 1.5; } // aggro mobs move around a bit more often if(PMob->m_Aggro != AGGRO_NONE && PMob->speed != 0) { PMob->setMobMod(MOBMOD_ROAM_COOL, 20); } // setup special ability if(mJob == JOB_RNG) { // giga if(PMob->m_Family == 126 && PMob->m_Family <= 130) { PMob->setMobMod(MOBMOD_SPECIAL_COOL, 35); // catapult PMob->setMobMod(MOBMOD_SPECIAL_SKILL, 402); } else { // all other rangers PMob->setMobMod(MOBMOD_SPECIAL_COOL, 20); PMob->setMobMod(MOBMOD_SPECIAL_SKILL, 16); } } else if(mJob == JOB_NIN) { PMob->setMobMod(MOBMOD_SPECIAL_COOL, 35); PMob->setMobMod(MOBMOD_SPECIAL_SKILL, 16); } else if(mJob == JOB_DRG && PMob->m_Family != 193) { PMob->setMobMod(MOBMOD_SPECIAL_COOL, 45); // sahigans if(PMob->m_Family == 213) { PMob->setMobMod(MOBMOD_SPECIAL_SKILL, 514); } else { // all other dragoons PMob->setMobMod(MOBMOD_SPECIAL_SKILL, 808); } } // all pets must be defined in the mob_pets file // set recast times for summoning pets if(PMob->loc.zone->GetType() != ZONETYPE_DYNAMIS) { if(mJob == JOB_BST) { PMob->setMobMod(MOBMOD_SPECIAL_COOL, 100); PMob->setMobMod(MOBMOD_SPECIAL_SKILL, 761); } else if(mJob == JOB_DRG && !isNM) { // only drgs in 3rd expansion calls wyvern as non-NM // include fomors if(PMob->loc.zone->GetContinentID() == THE_ARADJIAH_CONTINENT || PMob->m_Family == 115) { // 20 min recast PMob->setMobMod(MOBMOD_SPECIAL_SKILL, 476); PMob->setMobMod(MOBMOD_SPECIAL_COOL, 720); } } else if(mJob == JOB_PUP) { PMob->setMobMod(MOBMOD_SPECIAL_SKILL, 1645); PMob->setMobMod(MOBMOD_SPECIAL_COOL, 720); } } // ambush antlions if(PMob->m_Family == 357) { PMob->setMobMod(MOBMOD_SPECIAL_SKILL, 22); PMob->setMobMod(MOBMOD_SPECIAL_COOL, 1); PMob->m_specialFlags |= SPECIALFLAG_HIDDEN; PMob->m_roamFlags |= ROAMFLAG_AMBUSH; } // Phuabo if(PMob->m_Family == 194) { PMob->m_roamFlags |= ROAMFLAG_STEALTH; } // Yovra if(PMob->m_Family == 271) { PMob->m_roamFlags |= ROAMFLAG_STEALTH; } // Chigoe if(PMob->m_Family == 64) { PMob->m_roamFlags |= ROAMFLAG_STEALTH; } // Amphiptere if(PMob->m_Family == 6) { PMob->m_roamFlags |= ROAMFLAG_STEALTH; } if(PMob->m_Family == 362) { // rapido doesn't stop PMob->m_roamFlags |= ROAMFLAG_IGNORE; } // handle standback // mobs that stand back: blm, whm, rng, cor, nin if(mJob == JOB_RNG) { // giga if(PMob->m_Family == 126 && PMob->m_Family <= 130) { PMob->setMobMod(MOBMOD_STANDBACK_TIME, 20); } else if(PMob->m_Family == 199) { // they stay back forever PMob->setMobMod(MOBMOD_STANDBACK_TIME, 90); } else { PMob->setMobMod(MOBMOD_STANDBACK_TIME, 60); } } else if(mJob == JOB_COR) { PMob->setMobMod(MOBMOD_STANDBACK_TIME, 60); } else if(mJob == JOB_BLM) { PMob->setMobMod(MOBMOD_STANDBACK_TIME, 42); } else if(mJob == JOB_WHM) { PMob->setMobMod(MOBMOD_STANDBACK_TIME, 32); } else if(mJob == JOB_NIN) { PMob->setMobMod(MOBMOD_STANDBACK_TIME, 25); } // mobs with zero speed cannot standback if(PMob->speed == 0) { PMob->setMobMod(MOBMOD_STANDBACK_TIME, 0); } // special case, give spell list to my pet if(PMob->getMobMod(MOBMOD_PET_SPELL_LIST) && PMob->PPet != NULL) { // Stubborn_Dredvodd CMobEntity* PPet = (CMobEntity*)PMob->PPet; // give pet spell list PPet->m_SpellListContainer = mobSpellList::GetMobSpellList(PMob->getMobMod(MOBMOD_PET_SPELL_LIST)); } if(PMob->getMobMod(MOBMOD_SPELL_LIST)) { PMob->m_SpellListContainer = mobSpellList::GetMobSpellList(PMob->getMobMod(MOBMOD_SPELL_LIST)); } // TODO: this should be put into its own column // has not been decided where yet if(PMob->m_Family == 258 || PMob->m_Family == 276) { // makes worms roam by going into ground / back up PMob->m_roamFlags |= ROAMFLAG_WORM; } if(PMob->m_Aggro != AGGRO_NONE && PMob->loc.zone->GetType() == ZONETYPE_OUTDOORS) { PMob->m_roamFlags |= ROAMFLAG_MEDIUM; } else { PMob->m_roamFlags |= ROAMFLAG_SMALL; } if(PMob->m_roamFlags & ROAMFLAG_AMBUSH) { // always stay close to spawn PMob->m_maxRoamDistance = 2.0f; } // cap all stats for lvl / job for (int i=SKILL_DIV; i <=SKILL_BLU; i++) { uint16 maxSkill = battleutils::GetMaxSkill((SKILLTYPE)i,PMob->GetMJob(),PMob->GetMLevel()); if (maxSkill != 0) { PMob->WorkingSkills.skill[i] = maxSkill; } else //if the mob is WAR/BLM and can cast spell { // set skill as high as main level, so their spells won't get resisted uint16 maxSubSkill = battleutils::GetMaxSkill((SKILLTYPE)i,PMob->GetSJob(),PMob->GetMLevel()); if (maxSubSkill != 0) { PMob->WorkingSkills.skill[i] = maxSubSkill; } } } if(zoneType == ZONETYPE_DYNAMIS || zoneType == ZONETYPE_BATTLEFIELD) { // never despawn PMob->SetDespawnTimer(0); // do not roam around PMob->m_roamFlags |= ROAMFLAG_EVENT; PMob->m_maxRoamDistance = 0.5f; } if((zoneType == ZONETYPE_BATTLEFIELD) && (PMob->m_bcnmID != 864) && (PMob->m_bcnmID != 704)) { // bcnmID 864 (desires of emptiness) and 704 (darkness named) don't superlink // force all mobs in same instance to superlink // plus one in case id is zero PMob->setMobMod(MOBMOD_SUPERLINK, PMob->m_battlefieldID); } uint8 evaRank = battleutils::GetSkillRank(SKILL_EVA, PMob->GetMJob()); PMob->addModifier(MOD_DEF, GetBase(PMob,PMob->defRank)); PMob->addModifier(MOD_EVA, GetBase(PMob,evaRank)); PMob->addModifier(MOD_ATT, GetBase(PMob,PMob->attRank)); PMob->addModifier(MOD_ACC, GetBase(PMob,PMob->accRank)); SKILLTYPE mEvasionRating = SKILL_ELE; if(mLvl > 83) { mEvasionRating = SKILL_SWD; } //natural magic evasion PMob->addModifier(MOD_MEVA, battleutils::GetMaxSkill(mEvasionRating, JOB_RDM, mLvl)); if((PMob->m_Type & MOBTYPE_NOTORIOUS) && mJob == JOB_WHM && mLvl >= 25) { // whm nms have stronger regen effect PMob->addModifier(MOD_REGEN, PMob->GetMLevel()/4); } // add traits for sub and main AddTraits(PMob, mJob, mLvl); AddTraits(PMob, PMob->GetSJob(), PMob->GetSLevel()); }
bool Vehicle::AddPassenger(Unit* unit, int8 seatId) { /// @Prevent adding passengers when vehicle is uninstalling. (Bad script in OnUninstall/OnRemovePassenger/PassengerBoarded hook.) if (_status == STATUS_UNINSTALLING) { sLog->outDebug(LOG_FILTER_VEHICLES, "Passenger GuidLow: %u, Entry: %u, attempting to board vehicle GuidLow: %u, Entry: %u during uninstall! SeatId: %i", unit->GetGUIDLow(), unit->GetEntry(), _me->GetGUIDLow(), _me->GetEntry(), (int32)seatId); return false; } if (unit->GetVehicle() != this) return false; if (unit->GetTypeId() == TYPEID_PLAYER && unit->GetMap()->IsBattleArena()) return false; SeatMap::iterator seat; if (seatId < 0) // no specific seat requirement { for (seat = Seats.begin(); seat != Seats.end(); ++seat) if (!seat->second.Passenger && (seat->second.SeatInfo->CanEnterOrExit() || seat->second.SeatInfo->IsUsableByOverride() || CheckCustomCanEnter())) break; if (seat == Seats.end()) // no available seat return false; } else { seat = Seats.find(seatId); if (seat == Seats.end()) return false; if (seat->second.Passenger) { if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger)) passenger->ExitVehicle(); else seat->second.Passenger = 0; } ASSERT(!seat->second.Passenger); } sLog->outDebug(LOG_FILTER_VEHICLES, "Unit %s enter vehicle entry %u id %u dbguid %u seat %d", unit->GetName(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUIDLow(), (int32)seat->first); seat->second.Passenger = unit->GetGUID(); if (seat->second.SeatInfo->CanEnterOrExit()) { ASSERT(_usableSeatNum); --_usableSeatNum; if (!_usableSeatNum) { if (_me->GetTypeId() == TYPEID_PLAYER) _me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE); else _me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); } } if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING)) if (!(_me->ToCreature() && _me->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_VEHICLE_ATTACKABLE_PASSENGERS) && !(unit->ToCreature() && unit->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_VEHICLE_ATTACKABLE_PASSENGERS)) unit->AddUnitState(UNIT_STATE_ONVEHICLE); VehicleSeatEntry const* veSeat = seat->second.SeatInfo; unit->m_movementInfo.t_pos.m_positionX = veSeat->m_attachmentOffsetX; unit->m_movementInfo.t_pos.m_positionY = veSeat->m_attachmentOffsetY; unit->m_movementInfo.t_pos.m_positionZ = veSeat->m_attachmentOffsetZ; unit->m_movementInfo.t_pos.SetOrientation(0); unit->m_movementInfo.t_time = 0; // 1 for player unit->m_movementInfo.t_seat = seat->first; unit->m_movementInfo.t_guid = _me->GetGUID(); // Hackfix switch (veSeat->m_ID) { case 10882: unit->m_movementInfo.t_pos.m_positionX = 15.0f; unit->m_movementInfo.t_pos.m_positionY = 0.0f; unit->m_movementInfo.t_pos.m_positionZ = 30.0f; break; default: break; } if (_me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER && seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL) ASSERT(_me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE)) if (_me->IsInWorld()) { unit->SendClearTarget(); // SMSG_BREAK_TARGET unit->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures) // also adds MOVEMENTFLAG_ROOT Movement::MoveSplineInit init(*unit); init.DisableTransportPathTransformations(); init.MoveTo(unit->m_movementInfo.t_pos.m_positionX, unit->m_movementInfo.t_pos.m_positionY, unit->m_movementInfo.t_pos.m_positionZ); init.SetFacing(0.0f); init.SetTransportEnter(); init.Launch(); if (_me->GetTypeId() == TYPEID_UNIT) { if (_me->ToCreature()->IsAIEnabled) _me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true); // update all passenger's positions //Passenger's spline OR vehicle movement will update positions //RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation()); } } if (GetBase()->GetTypeId() == TYPEID_UNIT) sScriptMgr->OnAddPassenger(this, unit, seatId); return true; }
Vehicle::~Vehicle() { /// @Uninstall must be called before this. ASSERT(_status == STATUS_UNINSTALLING); for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr) { if (itr->second.Passenger.Guid) TC_LOG_ERROR("entities.vehicle", "Vehicle::~Vehicle (Entry: %u) has passenger %u in seat %u during destroy.", GetBase()->GetEntry(), itr->second.Passenger, itr->first); ASSERT(itr->second.IsEmpty()); // ASSERT(!itr->second.Passenger.Guid); } }