#!/usr/local/bin/perl -w # -*- perl -*- ###################################################################### # unequipitems.pl -- Unequip all items equipped by PC # Copyright (c) 2008 Tero Kivinen # All Rights Reserved. ###################################################################### # Program: unequipitems.pl # $Source: /u/samba/nwn/bin/RCS/unequipitems.pl,v $ # Author : $Author: kivinen $ # # (C) Tero Kivinen 2008 # # Creation : 20:31 Jan 21 2008 kivinen # Last Modification : 21:29 Jan 21 2008 kivinen # Last check in : $Date: 2008/01/21 19:30:34 $ # Revision number : $Revision: 1.2 $ # State : $State: Exp $ # Version : 1.17 # Edit time : 13 min # # Description : Unequip all items equipped by PC # # $Log: unequipitems.pl,v $ # Revision 1.2 2008/01/21 19:30:34 kivinen # Fixed bug where Repos_Index was not incremented when new item # was added to table. # # Revision 1.1 2008/01/21 18:46:35 kivinen # Created. # # $EndLog$ # # # # ###################################################################### # initialization require 5.6.0; package UnequipItems; use strict; use Getopt::Long; use File::Glob ':glob'; use Gff; use GffRead; use GffWrite; use Time::HiRes qw(time); use Pod::Usage; $Opt::verbose = 0; $Opt::no_write = 0; $Opt::backup = 0; ###################################################################### # Get version information open(PROGRAM, "<$0") || die "Cannot open myself from $0 : $!"; undef $/; $Prog::program = ; $/ = "\n"; close(PROGRAM); if ($Prog::program =~ /\$revision:\s*([\d.]*)\s*\$/i) { $Prog::revision = $1; } else { $Prog::revision = "?.?"; } if ($Prog::program =~ /version\s*:\s*([\d.]*\.)*([\d]*)\s/mi) { $Prog::save_version = $2; } else { $Prog::save_version = "??"; } if ($Prog::program =~ /edit\s*time\s*:\s*([\d]*)\s*min\s*$/mi) { $Prog::edit_time = $1; } else { $Prog::edit_time = "??"; } $Prog::version = "$Prog::revision.$Prog::save_version.$Prog::edit_time"; $Prog::progname = $0; $Prog::progname =~ s/^.*[\/\\]//g; $| = 1; ###################################################################### # Read rc-file if (defined($ENV{'HOME'})) { read_rc_file("$ENV{'HOME'}/.unequipitemsrc"); } ###################################################################### # Option handling Getopt::Long::Configure("no_ignore_case"); if (!GetOptions("config=s" => \$Opt::config, "verbose|v+" => \$Opt::verbose, "help|h" => \$Opt::help, "no-write|n" => \$Opt::no_write, "backup|b" => \$Opt::backup, "version|V" => \$Opt::version) || defined($Opt::help)) { usage(); } if (defined($Opt::version)) { print("\u$Prog::progname version " . "$Prog::version by Tero Kivinen.\n"); exit(0); } while (defined($Opt::config)) { my($tmp); $tmp = $Opt::config; undef $Opt::config; if (-f $tmp) { read_rc_file($tmp); } else { die "Config file $Opt::config not found: $!"; } } ###################################################################### # Main loop $| = 1; my($i, $t0, %args); %args = (); if (join(";", @ARGV) =~ /[*?]/) { my(@argv); foreach $i (@ARGV) { push(@argv, bsd_glob($i)); } @ARGV = @argv; } foreach $i (@ARGV) { my($gff, $j, %repos, $cnt); $args{'filename'} = $i; $t0 = time(); if ($Opt::verbose > 1) { print("Reading file $i...\n"); } $gff = GffRead::read(%args); if ($Opt::verbose > 2) { printf("Read done, %g seconds\n", time() - $t0); } undef %repos; foreach $j (@{$$gff{ItemList}}) { $repos{$$j{Repos_Index}} = 1; } $cnt = 1; foreach $j (@{$$gff{Equip_ItemList}}) { # Find next free location while (defined($repos{$cnt})) { $cnt++; } $$j{Repos_Index} = $cnt; $$j{'Repos_Index. ____type'} = 2; $cnt++; } push(@{$$gff{ItemList}}, @{$$gff{Equip_ItemList}}); $#{$$gff{Equip_ItemList}} = -1; if (!$Opt::no_write) { if ($Opt::backup) { if ($Opt::verbose > 1) { print("Renaming $i -> $i.bak...\n"); } rename($i, $i . ".bak"); } if ($Opt::verbose) { print("Writing file $i...\n"); } &GffWrite::write($gff, filename => $i); } } exit 0; ###################################################################### # Read rc file sub read_rc_file { my($file) = @_; my($next, $space); if (open(RCFILE, "<$file")) { while () { chomp; while (/\\$/) { $space = 0; if (/\s+\\$/) { $space = 1; } s/\s*\\$//g; $next = ; chomp $next; if ($next =~ s/^\s+//g) { $space = 1; } if ($space) { $_ .= " " . $next; } else { $_ .= $next; } } if (/^\s*([a-zA-Z0-9_]+)\s*$/) { eval('$Opt::' . lc($1) . ' = 1;'); } elsif (/^\s*([a-zA-Z0-9_]+)\s*=\s*\"([^\"]*)\"\s*$/) { my($key, $value) = ($1, $2); $value =~ s/\\n/\n/g; $value =~ s/\\t/\t/g; eval('$Opt::' . lc($key) . ' = $value;'); } elsif (/^\s*([a-zA-Z0-9_]+)\s*=\s*(.*)\s*$/) { my($key, $value) = ($1, $2); $value =~ s/\\n/\n/g; $value =~ s/\\t/\t/g; eval('$Opt::' . lc($key) . ' = $value;'); } } close(RCFILE); } } ###################################################################### # Usage sub usage { Pod::Usage::pod2usage(0); } =head1 NAME unequipitems - Modify bic file so that all equipped items are unequipped =head1 SYNOPSIS unequipitems [B<--help>|B<-h>] [B<--version>|B<-V>] [B<--verbose>|B<-v>] [B<--config> I] [B<--no-write>|B<-n>] [B<--backup>|B<-b>] I ... unequipitems B<--help> =head1 DESCRIPTION B moves all items in the Equip_ItemList to the ItemList, and makes sure each of them has unique Repos_Index. =head1 OPTIONS =over 4 =item B<--help> B<-h> Prints out the usage information. =item B<--version> B<-V> Prints out the version information. =item B<--verbose> B<-v> Enables the verbose prints. This option can be given multiple times, and each time it enables more verbose prints. =item B<--config> I All options given by the command line can also be given in the configuration file. This option is used to read another configuration file in addition to the default configuration file. =item B<--no-write> B<-n> Do not write anything, but do the modifications etc. This can be used to check that everything is modified properly before actually doing the modification. =item B<--backup> B<-b> Take backup copy of the file before writing it back. The backup copy will be named F. =back =head1 EXAMPLES unequipitems.pl *.bic unequipitems.pl -v -b */*.bic =head1 FILES =over 6 =item ~/.unequipitemsrc Default configuration file. =back =head1 SEE ALSO gffencode(1), gffmatch(1), gffmodify(1), gffprint(1), Gff(3), GffWrite(3), and GffRead(3). =head1 AUTHOR Tero Kivinen . =head1 HISTORY This program evolved from gffmodify(1) as gffmodify cannot modify structures, and this was created so Patch can enable ILR in his PW and not to cause all players with illegal items to be booted.