Exemple #1
0
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);
}
Exemple #2
0
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;
}
Exemple #3
0
/*
 * 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;
}
Exemple #4
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);
}
Exemple #5
0
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);
}
Exemple #6
0
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());
}
Exemple #8
0
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);
}
Exemple #9
0
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();
}
Exemple #10
0
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;
}
Exemple #11
0
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);
    }
}
Exemple #12
0
// 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;
}
Exemple #13
0
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);
}
Exemple #14
0
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);
		}
	}
}
Exemple #15
0
void VehicleKit::Initialize(uint32 creatureEntry)
{
    InstallAllAccessories(creatureEntry ? creatureEntry : GetBase()->GetEntry());
    UpdateFreeSeatCount();
    m_isInitialized = true;
}
Exemple #16
0
VehicleKit::~VehicleKit()
{
    Reset();
    GetBase()->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE);
}
Exemple #17
0
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;
}
Exemple #20
0
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;
}
Exemple #21
0
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 );
}
Exemple #22
0
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;
}
Exemple #23
0
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;
			}
		}
	}
}
Exemple #24
0
uint16 GetMagicEvasion(CMobEntity* PMob)
{
    uint8 mEvaRank = 3;

    return GetBase(PMob, mEvaRank);
}
Exemple #25
0
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);
    }
}
Exemple #26
0
void CAOPNormal::UpdateOnRemove(void)
{
    BaseClass::UpdateOnRemove();
    pAdminOP.UnhookEnt(GetBase(), this, GetIndex());
}
Exemple #27
0
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;
}
Exemple #28
0
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());
}
Exemple #29
0
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;
}
Exemple #30
0
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);
    }
}