Is there any easy/intuitive way to make boats appear on docking?
Printable View
Is there any easy/intuitive way to make boats appear on docking?
There is a packet that shows the boat effect, yes. You have to send it on arrival and on depart. What version are you working on?
Alright, figured that might be it. Not quite sure how i would go about automatizing it.
Also, i assume this process would have to repeated regardless of players being in the map?
And to answer your question, v.62
Guessing these might be the packets:
SPAWN_SPECIAL_MAPOBJECT = 0x86
REMOVE_SPECIAL_MAPOBJECT = 0x87
I'm not sure what's SPAWN_SPECIAL_MAPOBJECT or REMOVE_SPECIAL_MAPBOJECT are. I suggest taking a safe approach and looking at the .idb by @sunnyboy located in this thread.
As for the players - once you broadcast a packet to the dock map it will be broadcasted to every player in that map. If there are none - then no packet will be sent.
There are two packets that handle this if I recall correctly. I believe @kevintjuh93 knows more about this.
Your packet/headers may be wrong or outdated or your parameters are incorrect.
The BoatPacket/BoatEffect is known as ContiMove. (For moving from continent to continent) I never 100% coded ContiMove, but there's two packets.
1 is OnContiMove and 2 is OnContiState . OnContiMove is what handles Balrogs on the ship to Orbis if I recall, and OnContiState is what handles the view of the ship upon map entrance (ex: the ship shows a leave animation meaning you're too late)
I remember Nexon using a CRand32 to set the timestamp of when the event starts (balrog raid), however I could be wrong. Been some time since I've checked.
PHP Code:void __thiscall CField_ContiMove::OnPacket(CField_ContiMove *this, int nType, CInPacket *iPacket)
{
if ( nType == 0xA4 )
{
CField_ContiMove::OnContiMove((CField_ContiMove *)((char *)this - 8), iPacket);
}
else
{
if ( nType == 0xA5 )
CField_ContiMove::OnContiState((CField_ContiMove *)((char *)this - 8), iPacket);
else
CField::OnPacket(&this->baseclass_0, (ToClientPacket)nType, iPacket);
}
}
PHP Code:void __thiscall CField_ContiMove::OnContiMove(CField_ContiMove *this, CInPacket *iPacket)
{
CField_ContiMove *v2; // esi@1
v2 = this;
switch ( CInPacket::Decode1(iPacket) )
{
case 8:
CField_ContiMove::OnStartShipMoveField(v2, iPacket);
break;
case 0xA:
CField_ContiMove::OnMoveField(v2, iPacket);
break;
case 0xC:
CField_ContiMove::OnEndShipMoveField(v2, iPacket);
break;
default:
return;
}
}
PHP Code:void __thiscall CField_ContiMove::OnStartShipMoveField(CField_ContiMove *this, CInPacket *iPacket)
{
CField_ContiMove *v2; // esi@1
v2 = this;
if ( CInPacket::Decode1(iPacket) == CONTI_START )
CShip::LeaveShipMove(&v2->m_ship);
}
PHP Code:void __thiscall CField_ContiMove::OnMoveField(CField_ContiMove *this, CInPacket *iPacket)
{
CField_ContiMove *v2; // esi@1
int v3; // eax@1
v2 = this;
v3 = (unsigned __int8)CInPacket::Decode1(iPacket) - 4;
if ( v3 )
{
if ( v3 == 1 )
CShip::DisappearShip(&v2->m_ship);
}
else
{
CShip::AppearShip(&v2->m_ship);
}
}
PHP Code:void __thiscall CField_ContiMove::OnEndShipMoveField(CField_ContiMove *this, CInPacket *iPacket)
{
CField_ContiMove *v2; // esi@1
v2 = this;
if ( CInPacket::Decode1(iPacket) == 6 )
CShip::EnterShipMove(&v2->m_ship);
}
PHP Code:void __thiscall CField_ContiMove::OnContiState(CField_ContiMove *this, CInPacket *iPacket)
{
CField_ContiMove *v2; // esi@1
int v3; // edi@1
int v4; // eax@1
v2 = this;
v3 = (unsigned __int8)CInPacket::Decode1(iPacket);
v4 = (unsigned __int8)CInPacket::Decode1(iPacket);
switch ( v3 )
{
case 0:
case 1:
case 6:
if ( !v2->m_ship.m_nShipKind )
CShip::EnterShipMove(&v2->m_ship);
break;
case 3:
case 4:
if ( v2->m_ship.m_nShipKind == 1 && v4 == 1 )
CShip::AppearShip(&v2->m_ship);
goto $LN3_66;
case 2:
case 5:
$LN3_66:
if ( !v2->m_ship.m_nShipKind )
CShip::LeaveShipMove(&v2->m_ship);
break;
default:
return;
}
}
The values in the enum applies to both packets and every byte that is read. It will make a lot of sense if you sum it up!PHP Code:FFFFFFFF ; enum CONTI
FFFFFFFF CONTI_DORMANT = 0
FFFFFFFF CONTI_WAIT = 1
FFFFFFFF CONTI_START = 2
FFFFFFFF CONTI_MOVE = 3
FFFFFFFF CONTI_MOBGEN = 4
FFFFFFFF CONTI_MOBDESTROY = 5
FFFFFFFF CONTI_END = 6
FFFFFFFF CONTI_TARGET_STARTFIELD = 7
FFFFFFFF CONTI_TARGET_START_SHIPMOVE_FIELD = 8
FFFFFFFF CONTI_TARGET_WAITFIELD = 9
FFFFFFFF CONTI_TARGET_MOVEFIELD = 0Ah
FFFFFFFF CONTI_TARGET_ENDFIELD = 0Bh
FFFFFFFF CONTI_TARGET_END_SHIPMOVE_FIELD = 0Ch
62 Headers and Packets with my comments. Enjoy.
PHP Code:/*
HEADER: 0x6F
B1
B2
8,2 = boat leaves 0208 -> 520
10, 4 = balrog boat appears 040A -> 1034
10, 5 = balrog boat leaves -> 050A -> 1290
12, 6 = boat arrives 060C -> 1548
*/
public static MaplePacket showBoatEffect(int effect) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.CONTI_MOVE.getValue());
mplew.writeShort(effect);
return mplew.getPacket();
}
/*
HEADER: 0x70 (does same thing has 0x6F)
B1
B2
B1 == 0/1 -> enter move
B1 == 2 -> ship leave
B1 == 3/4 and B2 == 1 -> ship appears
*/
public static MaplePacket showBoatEffect1(byte a, byte b) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.CONTI_STATE.getValue());
mplew.write(a);
mplew.write(b);
return mplew.getPacket();
}
Thanks for all the help!
Regards