Skip to content

Instantly share code, notes, and snippets.

@cydh
Last active April 29, 2016 11:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cydh/e1473eb2a242d221e80a42dce4ed7093 to your computer and use it in GitHub Desktop.
Save cydh/e1473eb2a242d221e80a42dce4ed7093 to your computer and use it in GitHub Desktop.
Source for select item list window by Change Material and Four Spirits Analysis skill. Added 2 commands `cm` for Change Material and `analysis` for Four Spirits Analysis that only can be used after skill is casted. Now, you can make simple macro! See https://gist.github.com/cydh/e8167633881f44c76759943a3a1e66ab
Index: src/Commands.pm
===================================================================
--- src/Commands.pm (revision 9032)
+++ src/Commands.pm (working copy)
@@ -236,6 +236,10 @@
southeast => \&cmdManualMove,
southwest => \&cmdManualMove,
captcha => \&cmdAnswerCaptcha
+
+ # [Cydh]
+ cm => \&cmdItemExchange,
+ analysis => \&cmdItemExchange,
);
}
@@ -5989,4 +5993,83 @@
message $msg, "list";
}
+#######################################
+# 'cm' for Change Material (Genetic)
+# 'analysis' for Four Spirit Analysis (Sorcerer) [Untested yet]
+# @author [Cydh]
+#######################################
+sub cmdItemExchange {
+ if (!$net || $net->getState() != Network::IN_GAME) {
+ error TF("You must be logged in the game to use this command '%s'\n", shift);
+ return;
+ }
+ my ($switch, $args) = @_;
+ my $type;
+ my $typename;
+
+ if ($switch eq "cm") {
+ if ($exChangeItemSkill != 1) { # Change Material (2494)
+ error TF("This command only available after 'Change Material' skill is used!\n");
+ return;
+ }
+ $type = 0;
+ $typename = "Change Material";
+ } elsif ($switch eq "analysis") {
+ if ($exChangeItemSkill == 1) { # Four Spirit Analysis (2462)
+ error TF("This command only available after 'Four Spirit Analysis' skill used!\n");
+ return;
+ }
+ $type = $exChangeItemSkill-1;
+ $typename = "Four Spirit Analysis";
+ } else {
+ error TF("This command only available after 'Change Material' or 'Four Spirit Analysis' skill is used!\n");
+ return;
+ }
+
+ if ($args eq "cancel" || $args eq "end" || $args eq "no") {
+ my @items = ();
+ message TF("Item Exchange %s is canceled.\n", $typename), "info";
+ $messageSender->sendItemListWindowSelected(0, $type, 1, \@items);
+ undef $exChangeItemSkill;
+ return;
+ }
+
+ my ($item1, $amt1) = $args =~ /^(\d+) (\d+)/;
+
+ if ($item1 >= 0 and $amt1 > 0) {
+ my @list = split(/,/, $args);
+ my @items = ();
+
+ @list = grep(!/^$/, @list); # Remove empty entries
+ foreach (@list) {
+ my ($invIndex, $amt) = $_ =~ /^(\d+) (\d+)/;
+ my $item = $char->inventory->get($invIndex);
+ if ($item) {
+ if ($item->{amount} < $amt) {
+ warning TF("Invalid amount! You only have %dx of %s (%d).\n", $item->{amount}, $item->{name}, $invIndex);
+ } elsif ($item->{equipped} != 0) {
+ warning TF("Attempted to select equipped item %s (%d)!\n", $item->{name}, $invIndex);
+ } else {
+ message TF("Selected: %dx %s\n", $amt, $item->{name}), "info";
+ push(@items,{itemIndex => $item->{index}, amount => $amt });
+ }
+ } else {
+ warning TF("Item in index '%d' doesn't exists.\n", $invIndex);
+ }
+ }
+ if (@items > 0) {
+ my $num = scalar @items;
+ message TF("Items selected for %s: %d\n", $typename, $num), "info";
+ $messageSender->sendItemListWindowSelected($num, $type, 1, \@items);
+ } else {
+ error T("No items were selected.\n");
+ }
+ } else {
+ error T("Syntax Error in function '%s'\n" .
+ "Single Item: %s <item #> <amount>\n" .
+ "Combination: %s <item #> <amount>,<item #> <amount>,<item #> <amount>\n", $switch, $switch, $switch);
+ }
+ undef $exChangeItemSkill;
+}
+
1;
\ No newline at end of file
Index: src/functions.pl
===================================================================
--- src/functions.pl (revision 9032)
+++ src/functions.pl (working copy)
@@ -655,6 +655,7 @@
undef $repairList;
undef $devotionList;
undef $cookingList;
+ undef $exChangeItemSkill;
$captcha_state = 0;
$itemsList->clear();
Index: src/Globals.pm
===================================================================
--- src/Globals.pm (revision 9032)
+++ src/Globals.pm (working copy)
@@ -28,7 +28,7 @@
our %EXPORT_TAGS = (
config => [qw(%arrowcraft_items %avoid @chatResponses %cities_lut %config %consoleColors %directions_lut %equipTypes_lut %equipSlot_rlut %equipSlot_lut %haircolors @headgears_lut @msgTable %items_control %items_lut %itemSlotCount_lut %itemsDesc_lut %itemTypes_lut %jobs_lut %maps_lut %masterServers %monsters_lut %npcs_lut %packetDescriptions %portals_lut %responses %sex_lut %shop %skillsDesc_lut %lookHandle %skillsArea %skillsEncore %spells_lut %emotions_lut %timeout $char %mon_control %priority %routeWeights %pickupitems %rpackets %itemSlots_lut %statusHandle %statusName %effectName %portals_los %stateHandle %ailmentHandle %mapTypeHandle %mapPropertyTypeHandle %mapPropertyInfoHandle %elements_lut %mapAlias_lut %quests_lut)],
ai => [qw(@ai_seq @ai_seq_args %ai_v $AI $AI_forcedOff %targetTimeout)],
- state => [qw($accountID $cardMergeIndex @cardMergeItemsID $charID @chars @chars_old %cart @friendsID %friends %incomingFriend $field %homunculus $itemsList @itemsID %items $monstersList @monstersID %monsters @npcsID %npcs $npcsList @playersID %players @portalsID @portalsID_old %portals %portals_old $portalsList @storeList $currentChatRoom @currentChatRoomUsers @chatRoomsID %createdChatRoom %chatRooms @skillsID %storage @storageID $storageTitle @arrowCraftID %guild %incomingGuild @spellsID %spells @unknownPlayers @unknownNPCs $useArrowCraft %currentDeal %incomingDeal %outgoingDeal @identifyID @partyUsersID %incomingParty @petsID %pets @venderItemList $venderID $venderCID @venderListsID @buyerItemList @selfBuyerItemList $buyerID $buyingStoreID @buyerListsID @articles $articles %venderLists %buyerLists %monsters_old @monstersID_old %npcs_old %items_old %players_old @playersID_old @servers $sessionID $sessionID2 $accountSex $accountSex2 $map_ip $map_port $KoreStartTime $secureLoginKey $initSync $lastConfChangeTime $petsList $playersList $portalsList @playerNameCacheIDs %playerNameCache %pet $pvp @cashList $slavesList @slavesID %slaves %cashShop)],
+ state => [qw($accountID $cardMergeIndex @cardMergeItemsID $charID @chars @chars_old %cart @friendsID %friends %incomingFriend $field %homunculus $itemsList @itemsID %items $monstersList @monstersID %monsters @npcsID %npcs $npcsList @playersID %players @portalsID @portalsID_old %portals %portals_old $portalsList @storeList $currentChatRoom @currentChatRoomUsers @chatRoomsID %createdChatRoom %chatRooms @skillsID %storage @storageID $storageTitle @arrowCraftID %guild %incomingGuild @spellsID %spells @unknownPlayers @unknownNPCs $useArrowCraft %currentDeal %incomingDeal %outgoingDeal @identifyID @partyUsersID %incomingParty @petsID %pets @venderItemList $venderID $venderCID @venderListsID @buyerItemList @selfBuyerItemList $buyerID $buyingStoreID @buyerListsID @articles $articles %venderLists %buyerLists %monsters_old @monstersID_old %npcs_old %items_old %players_old @playersID_old @servers $sessionID $sessionID2 $accountSex $accountSex2 $map_ip $map_port $KoreStartTime $secureLoginKey $initSync $lastConfChangeTime $petsList $playersList $portalsList @playerNameCacheIDs %playerNameCache %pet $pvp @cashList $slavesList @slavesID %slaves %cashShop $exChangeItemSkill)],
network => [qw($remote_socket $net $messageSender $charServer $conState $conState_tries $encryptVal $ipc $bus $masterServer $lastSwitch $packetParser $clientPacketHandler $bytesSent $incomingMessages $outgoingClientMessages $enc_val1 $enc_val2 $captcha_state)],
interface => [qw($interface)],
misc => [qw($quit $reconnectCount @lastpm %lastpm @privMsgUsers %timeout_ex $shopstarted $dmgpsec $totalelasped $elasped $totaldmg %overallAuth %responseVars %talk $startTime_EXP $startingzeny @monsters_Killed $bExpSwitch $jExpSwitch $totalBaseExp $totalJobExp $shopEarned %itemChange $XKore_dontRedirect $monkilltime $monstarttime $startedattack $firstLoginMap $sentWelcomeMessage $versionSearch $monsterBaseExp $monsterJobExp %descriptions %flags %damageTaken $logAppend @sellList $userSeed $taskManager $repairList $mailList $auctionList $questList $hotkeyList $devotionList $cookingList %charSvrSet @deadTime)],
@@ -469,6 +469,7 @@
our %playerNameCache;
our %pet;
our @cashList;
+our $exChangeItemSkill
# Network
our $remote_socket; # Unused, but required for outdated plugins
Index: src/Network/Receive/idRO.pm
===================================================================
--- src/Network/Receive/idRO.pm (revision 9032)
+++ src/Network/Receive/idRO.pm (working copy)
@@ -15,6 +15,9 @@
use strict;
use base 'Network::Receive::ServerType0';
+use Log qw(message);
+use Globals qw($exChangeItemSkill);
+use Translation;
sub new {
my ($class) = @_;
@@ -25,6 +28,7 @@
#'007C' => ['actor_connected', 'C a4 v14 C2 a3 C2', [qw(object_type ID walk_speed opt1 opt2 option hair_style weapon lowhead type shield tophead midhead hair_color clothes_color head_dir stance sex coords unknown1 unknown2)]], # 42 # spawning
'0097' => ['private_message', 'v Z24 V Z*', [qw(len privMsgUser flag privMsg)]], # -1
#'022C' => ['actor_moved', 'C a4 v3 V v5 V v5 a4 a2 v V C2 a6 C2 v', [qw(object_type ID walk_speed opt1 opt2 option type hair_style weapon shield lowhead tick tophead midhead hair_color clothes_color head_dir guildID emblemID manner opt3 stance sex coords unknown1 unknown2 lv)]], # 65 # walking
+ '07E3' => ['skill_exchange_item', 'V2', [qw(type val)]], # 8
);
foreach my $switch (keys %packets) {
@@ -43,4 +47,22 @@
return $self;
}
+sub skill_exchange_item {
+ my ($self, $args) = @_;
+ if ($args->{type} == 0) {
+ message TF("Change Material is ready to use. Follow it by using command 'cm'.\n"), "info";
+ } else {
+ message TF("Four Spirit Analysis is ready to use. Follow it by using command 'analysis'.\n"), "info";
+ }
+ ##############################
+ # $args->{type} : Type
+ # 0: Change Material
+ # 1: Elemental Analysis Lv 1
+ # 2: Elemental Analysis Lv 2
+ # This value will be added +1 for simple check later
+ # $args->{val} : ????
+ ##############################
+ $exChangeItemSkill = $args->{type} + 1;
+}
+
1;
\ No newline at end of file
Index: src/Network/Send.pm
===================================================================
--- src/Network/Send.pm (revision 9032)
+++ src/Network/Send.pm (working copy)
@@ -31,7 +31,7 @@
use Digest::MD5;
use Math::BigInt;
-use Globals qw(%config $encryptVal $bytesSent $conState %packetDescriptions $enc_val1 $enc_val2 $char $masterServer $syncSync $accountID %timeout %talk);
+use Globals qw(%config $encryptVal $bytesSent $conState %packetDescriptions $enc_val1 $enc_val2 $char $masterServer $syncSync $accountID %timeout %talk $exChangeItemSkill);
use I18N qw(bytesToString stringToBytes);
use Utils qw(existsInList getHex getTickCount getCoordString makeCoordsDir);
use Misc;
@@ -1207,4 +1207,40 @@
debug "Sent Forge, Produce Item: $ID\n" , 2;
}
+#######################################
+# sendItemListWindowSelected
+# @param num Number of items
+# @param type 0: Change Material
+# 1: Elemental Analysis (Level 1: Pure to Rough)
+# 2: Elemental Analysis (Level 1: Rough to Pure)
+# @param act 0: Cancel
+# 1: Process
+# @param r_items List of items
+# @author [Cydh]
+#######################################
+sub sendItemListWindowSelected {
+ my ($self, $num, $type, $act, $r_items) = @_;
+ my $len = ($num * 4) + 12;
+ $self->sendToServer($self->reconstruct({
+ switch => 'item_list_window_selected',
+ len => $len,
+ type => $type,
+ act => $act,
+ items => $r_items,
+ }));
+ #debug "Sent change material: ".(join ', ', map {"$_->{itemIndex} x $_->{amount}"} @$r_items)."\n", "sendPacket";
+ undef $exChangeItemSkill;
+}
+
+sub parse_item_list_window_selected {
+ my ($self, $args) = @_;
+ @{$args->{items}} = map {{ itemIndex => unpack('v', $_), amount => unpack('v', $_) }} unpack '(a4)*', $args->{itemInfo};
+}
+
+sub reconstruct_item_list_window_selected {
+ my ($self, $args) = @_;
+ $args->{itemInfo} = pack '(a4)*', map { pack 'v2', @{$_}{qw(itemIndex amount)} } @{$args->{items}};
+}
+#########################
+
1;
\ No newline at end of file
Index: src/Network/Send/ServerType0.pm
===================================================================
--- src/Network/Send/ServerType0.pm (revision 9032)
+++ src/Network/Send/ServerType0.pm (working copy)
@@ -112,6 +112,7 @@
'0437' => ['character_move','a3', [qw(coords)]],
'0443' => ['skill_select', 'V v', [qw(why skillID)]],
'07D7' => ['party_setting', 'V C2', [qw(exp itemPickup itemDivision)]],
+ '07E4' => ['item_list_window_selected', 'v V V a*', [qw(len type act itemInfo)]],
'0801' => ['buy_bulk_vender', 'x2 a4 a4 a*', [qw(venderID venderCID itemInfo)]], #Selling store
'0802' => ['booking_register', 'v8', [qw(level MapID job0 job1 job2 job3 job4 job5)]],
'0804' => ['booking_search', 'v3 V s', [qw(level MapID job LastIndex ResultCount)]],
Copy link

ghost commented Apr 29, 2016

Hi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment