From 4621e85ef58ea33849f49468e0e19a5a2724f9af Mon Sep 17 00:00:00 2001
From: ElTata <eltata@firemail.cc>
Date: Fri, 4 Oct 2019 18:04:55 +0200
Subject: [PATCH] classes wip:

- new command to choose a new class
- everything seems ready
- youhou
---
 Irpg/Action.pm          | 19 ++++++---
 Irpg/Classes/Mage.pm    |  2 +-
 Irpg/Classes/Thief.pm   |  2 +-
 Irpg/Classes/Warrior.pm |  2 +-
 Irpg/Main.pm            | 26 +++++++----
 Irpg/Users.pm           | 95 ++++++++++++++++++++++++++++++++---------
 Irpg/Utils.pm           | 13 ++++--
 7 files changed, 119 insertions(+), 40 deletions(-)

diff --git a/Irpg/Action.pm b/Irpg/Action.pm
index a2c4cd2..8812cb5 100644
--- a/Irpg/Action.pm
+++ b/Irpg/Action.pm
@@ -242,10 +242,17 @@ sub perform_action {
     my $p2sum = itemsum($p2,1);
     my $p1roll = int(rand($p1sum) * $p1atk);
     my $p2roll = int(rand($p2sum) * $p2def);
-	my $ret = {
-			p1sum=>int($p1sum/5), p2sum=>int($p2sum/5),
-			p1roll=>int($p1roll/5), p2roll=>int($p2roll/5),
-			vict=>0};
+	my $ret;
+	if ($p1roll < 5 || $p2roll < 5 || $p1sum < 5 || $p2roll < 5) {
+		$ret = {p1sum=>int($p1sum), p2sum=>int($p2sum),
+				p1roll=>int($p1roll), p2roll=>int($p2roll),
+				vict=>0};
+	}
+	else {
+		$ret = {p1sum=>int($p1sum/5), p2sum=>int($p2sum/5),
+				p1roll=>int($p1roll/5), p2roll=>int($p2roll/5),
+				vict=>0};
+	}
     if ($p1roll >= $p2roll) {
 		# VICTORY
 		$ret->{vict}++;
@@ -311,7 +318,7 @@ sub collision_action {
 					'made '.pronoun(3, $rps->{$p2}{gender}).
 						' lost '.pronoun(2, $rps->{$p2}{gender}):
 					'lost '.pronoun(2, $rps->{$p1}{gender})).
-				" mind !";
+				" minds !";
 	}
 	else { #($action_type eq 'steal')
 		$mesg .= ($ret_action->{vict} ?
@@ -401,7 +408,7 @@ sub do_action {
 			"an undefined deed, but collapses out of exhaustion.");
 		return;
 	}
-	if ($rps->{$username}{action} < 2 && exists($arg[0])) {
+	if ($rps->{$username}{actions} < 2 && exists($arg[0])) {
 		Irpg::Irc::notice("You do not have enough energy to ".
 			"look for anyone.", $usernick);
 		Irpg::Irc::chanmsg("$username tries to contact someone, but ".
diff --git a/Irpg/Classes/Mage.pm b/Irpg/Classes/Mage.pm
index 1ee0538..5b72442 100644
--- a/Irpg/Classes/Mage.pm
+++ b/Irpg/Classes/Mage.pm
@@ -3,7 +3,7 @@ package Irpg::Classes::Mage;
 use strict;
 use warnings;
 use Irpg::Classes::Farmer;
-our @ISA = qw(Farmer);
+our @ISA = qw(Irpg::Classes::Farmer);
 
 sub new {
 	my ($class, $pl_stats) = @_;
diff --git a/Irpg/Classes/Thief.pm b/Irpg/Classes/Thief.pm
index 0d76763..f126bb6 100644
--- a/Irpg/Classes/Thief.pm
+++ b/Irpg/Classes/Thief.pm
@@ -3,7 +3,7 @@ package Irpg::Classes::Thief;
 use strict;
 use warnings;
 use Irpg::Classes::Farmer;
-our @ISA = qw(Farmer);
+our @ISA = qw(Irpg::Classes::Farmer);
 
 sub new {
 	my ($class, $pl_stats) = @_;
diff --git a/Irpg/Classes/Warrior.pm b/Irpg/Classes/Warrior.pm
index 181dcee..18fc5ca 100644
--- a/Irpg/Classes/Warrior.pm
+++ b/Irpg/Classes/Warrior.pm
@@ -3,7 +3,7 @@ package Irpg::Classes::Warrior;
 use strict;
 use warnings;
 use Irpg::Classes::Farmer;
-our @ISA = qw(Farmer);
+our @ISA = qw(Irpg::Classes::Farmer);
 
 sub new {
 	my ($class, $pl_stats) = @_;
diff --git a/Irpg/Main.pm b/Irpg/Main.pm
index d4c2f66..006d0ad 100644
--- a/Irpg/Main.pm
+++ b/Irpg/Main.pm
@@ -143,19 +143,25 @@ sub penalize {
 		$pen_key = 'pen_quit';
     }
     elsif ($type eq "nick") {
-        my $newnick = shift;
         $pen = int(30 * ($opts->{rppenstep}**$rps->{$username}{level}));
-        $rps->{$username}{nick} = substr($newnick,1);
-        substr($rps->{$username}{userhost},0,length($rps->{$username}{nick})) =
-            substr($newnick,1);
 		$reason = "nick change";
         $pen_key = 'pen_nick';
     }
+	elsif ($type eq "align") {
+        $pen = int(30 * ($opts->{rppenstep}**$rps->{$username}{level}));
+		$reason = 'alignment change';
+		$pen_key = 'pen_align';
+	}
 	elsif ($type eq "chtitle") {
         $pen = int(30 * ($opts->{rppenstep}**$rps->{$username}{level}));
 		$reason = 'title change';
 		$pen_key = 'pen_title';
 	}
+	elsif ($type eq "chclass") {
+		$pen = int($opts->{rpbase} * ($opts->{rpstep}**$rps->{$username}{level}));
+		$reason = 'training';
+		$pen_key = 'pen_class';
+	}
     elsif ($type eq "privmsg" || $type eq "notice") {
 		#$pen = int(shift(@_) * ($opts->{rppenstep}**$rps->{$username}{level}));
         $pen = -int(shift(@_) * $rps->{$username}{level} / 5);
@@ -164,13 +170,11 @@ sub penalize {
     }
     elsif ($type eq "part") {
         $pen = int(200 * ($opts->{rppenstep}**$rps->{$username}{level}));
-        $rps->{$username}{online}=0;
 		$reason = 'parting';
         $pen_key = 'pen_part';
     }
     elsif ($type eq "kick") {
         $pen = int(250 * ($opts->{rppenstep}**$rps->{$username}{level}));
-        $rps->{$username}{online}=0;
 		$reason = 'being kicked';
         $pen_key = 'pen_kick';
     }
@@ -418,19 +422,25 @@ sub parse {
         # us who just lost it
         elsif ($usernick eq $primnick) { Irpg::Irc::sts("NICK $primnick",1); }
         else {
-            penalize($username,"nick",$arg[2]);
+			$rps->{$username}{nick} = substr($arg[2],1);
+			substr($rps->{$username}{userhost},0,length($rps->{$username}{nick})) =
+				substr($arg[2],1);
+            penalize($username,"nick");
 			if (exists($onchan{$usernick})) {
 				$onchan{substr($arg[2],1)} = delete($onchan{$usernick});
 			}
         }
     }
     elsif ($arg[1] eq 'part') {
+        $rps->{$username}{online}=0;
         penalize($username,"part");
         delete($onchan{$usernick}) if ($opts->{botchan} eq substr($arg[2], 1));
     }
     elsif ($arg[1] eq 'kick') {
         $usernick = $arg[3];
-        penalize(finduser($usernick),"kick");
+		$username = finduser($usernick);
+        $rps->{$usernick}{online}=0;
+        penalize($username,"kick");
         delete($onchan{$usernick}) if ($opts->{botchan} eq $arg[2]);
     }
     # don't penalize /notices to the bot
diff --git a/Irpg/Users.pm b/Irpg/Users.pm
index d96fe53..1677c31 100644
--- a/Irpg/Users.pm
+++ b/Irpg/Users.pm
@@ -118,7 +118,8 @@ sub register {
 			}
 			for my $pen ("pen_mesg","pen_nick","pen_part",
 						 "pen_kick","pen_quit","pen_quest",
-						 "pen_logout","pen_logout","pen_title") {
+						 "pen_logout","pen_logout","pen_title",
+					 	 "pen_align","pen_class") {
 				$rps->{$arg[0]}{$pen} = 0;
 			}
 			Irpg::Irc::chanmsg("Welcome $usernick\'s new player $arg[0], the ".
@@ -197,7 +198,7 @@ sub logout {
 	my ($userhost, $usernick, $username, $source, @arg) = @_;
 	if (defined($username)) {
         $rps->{$username}{online}=0;
-		penalize($username,"logout");
+		Irpg::Main::penalize($username,"logout");
 	}
 	else {
 		Irpg::Irc::privmsg("You are not logged in.", $usernick);
@@ -273,6 +274,7 @@ sub align {
 				".");
 		Irpg::Irc::privmsg("Your alignment was changed to ".lc($arg[0]).".",
 				$source);
+		Irpg::Main::penalize($username,"align");
 	}
 }
 
@@ -349,17 +351,23 @@ sub points {
 		Irpg::Irc::notice("You are not logged in.", $usernick);
 		return;
 	}
+	if (!@arg) {
+		Irpg::Irc::privmsg("Your raw competences are the following: ".
+			join(', ', map { uc($_)." $rps->{$username}{stats}{$_}" }
+						keys($rps->{$username}{stats})).".", $source);
+		return;
+	}
 	if (@arg != 2 || $arg[1] !~ m/^\d+$/) {
-		Irpg::Irc::privmsg("Try: POINTS <stat> <n>",$usernick);
+		Irpg::Irc::notice("Try: POINTS <stat> <n>",$usernick);
 		return;
 	}
 	my ($stat, $n) = @arg;
 	if ($n > $rps->{$username}{points}) {
-		Irpg::Irc::privmsg("You do not have that much points to spend.", $usernick);
+		Irpg::Irc::privmsg("You do not have that much points to spend.", $source);
 		return;
 	}
 	if (!grep { $stat } qw(str con wis int cha dex)) {
-		Irpg::Irc::privmsg("'$stat' is not a valid stat name.", $usernick);
+		Irpg::Irc::privmsg("'$stat' is not a valid stat name.", $source);
 		return	
 	}
 
@@ -368,19 +376,61 @@ sub points {
 	Irpg::Irc::privmsg("Ok!", $usernick);
 }
 
-sub testclass {
+sub class {
 	my ($userhost, $usernick, $username, $source, @arg) = @_;
+	my $cname = exists($arg[0]) ? lc($arg[0]) : ''; # lower case
+	$cname =~ s/(\w)/\u$1/;	 # capitalize the first letter
 	if (!defined($username)) {
 		Irpg::Irc::notice("You are not logged in.", $usernick);
+		return;
+	}
+	elsif (!$cname) {
+		$cname = $rps->{$username}{class}->{NAME};
+		Irpg::Irc::privmsg("You are a".($cname =~ m/^[aeiouyæœ].*/ ? 'n':'').
+			" $cname with the following stats: ".
+			join(', ', map { uc($_)." ".eval('$rps->{$username}{class}->'.$_.'()') }
+						keys($rps->{$username}{stats})).".",$source);
+		return;
+	}
+	my @classes;
+	foreach (<Irpg/Classes/*.pm>) {
+		s/Irpg\/Classes\/(\w+)\.pm/$1/;
+		push @classes, $_;
+	}
+	if (!grep { $cname eq $_ } @classes) {
+		Irpg::Irc::privmsg("I know you are a very special unique person ".
+			"with your very own feelings, sensitivity, emotions, ".
+			"competences and everything, but you really can't be ".
+			"a".($cname =~ m/^[AEIOUYƌ].*/ ? 'n':'')." '$cname'. ".
+			"Too bad :(.", $source);
+	}
+	elsif ($cname eq $rps->{$username}{class}->{NAME}) {
+		Irpg::Irc::privmsg("You already ARE a".
+			($cname =~ m/^[AEIOUYƌ].*/ ? 'n':'')." '$cname', and ".
+			"your are making a fool of yourself... This is really awkward.",
+			$source)
 	}
 	else {
-		Irpg::Irc::privmsg("Classe ".
-			$rps->{$username}{class}->{NAME}.
-			" Raw stats : ".
-			join(', ', map { "$_ $rps->{$username}{stats}{$_}" } keys($rps->{$username}{stats})).
-			" Modified stats : ".
-			join(', ', map { "$_ ".eval('$rps->{$username}{class}->'.$_.'()') } keys($rps->{$username}{stats})).
-			"", $source);
+		eval "require Irpg::Classes::$cname";
+		my $new_class = eval 'Irpg::Classes::'.$cname.'->new($rps->{$username}{stats})';
+		if ($new_class) {
+			$rps->{$username}{class} = $new_class;
+			Irpg::Main::penalize($username, 'chclass');
+			# show the new class
+			class($userhost,$usernick,$username,$source);
+			Irpg::Irc::chanmsg("$username has trained hard following the ".
+				"demanding path ".pronoun(1, $rps->{$username}{gender}).
+				" has chosen, and ".pronoun(2, $rps->{$username}{gender}).
+				" efforts paid back as ".pronoun(1, $rps->{$username}{gender}).
+				" today rises as proud $cname.");
+		}
+		else {
+			Irpg::Irc::privmsg("You tried the best you could, ".
+				"but it seems you are lacking something... You do not ".
+				"match the criteria to be part of the people going ".
+				"by the name of ${cname}s, and as such, you are ".
+				"kept away from their privileges.", $source);
+		}
 	}
 }
 
@@ -405,10 +455,12 @@ our $commands = {
 				 hlp => 'NEWPASS <new password> : change password.'},
 
 	chtitle	 => {ref => \&chtitle,	adm => 0, prv => 1, pub => 1,
-				 hlp => 'CHTITLE <new title> : change title.'},
+				 hlp => 'CHTITLE <new title> : change title. '.
+			 			'Changing title is a p30 action.'},
 
 	align	 => {ref => \&align,	adm => 0, prv => 1, pub => 1,
-				 hlp => 'ALIGN <good|neutral|evil> : change alignment.'},
+				 hlp => 'ALIGN <good|neutral|evil> : change alignment. '.
+			 			'Changing alignment is a p30 action.'},
 
 	gender	 => {ref => \&gender,	adm => 0, prv => 1, pub => 1,
 				 hlp => 'GENDER <F|N|M> : change your gender.'},
@@ -425,11 +477,14 @@ our $commands = {
 				 hlp => 'INFO : get some info about the bot.'},
 
 	points	 => {ref => \&points,	adm => 0, prv => 1, pub => 0,
-				 hlp => 'POINTS <stat> <n> : adds n points to your stat. '.
-				 		'stats are [str, con, wis, int, cha, dex].'},
-
-	class	 => {ref => \&testclass, adm => 0, prv => 1, pub => 1,
-				 hlp => 'CLASS : class info'}
+				 hlp => 'POINTS [<stat> <n>] : shows your points repartition, '.
+				 		'or adds n points to your stat. '.
+				 		'stats are {str, con, wis, int, cha, dex}.'},
+
+	class	 => {ref => \&class, adm => 0, prv => 1, pub => 1,
+				 hlp => 'CLASS [<class name>]: gives your class info, '.
+			 			'or tries to change your class. Changing class cost '.
+						'the TTL of your level.'}
 };
 
 1;
diff --git a/Irpg/Utils.pm b/Irpg/Utils.pm
index 34a5de1..93d8a0b 100644
--- a/Irpg/Utils.pm
+++ b/Irpg/Utils.pm
@@ -245,8 +245,8 @@ sub loaddb { # load the players database
         chomp($l);
         next if $l =~ /^#/; # skip comments
         my @i = split("\t",$l);
-        print Dumper(@i) if @i != 44;
-        if (@i != 44) {
+        print Dumper(@i) if @i != 46;
+        if (@i != 46) {
 			Irpg::Irc::sts("QUIT: Anomaly in loaddb(); line $. of $opts->{dbfile} has ".
                 "wrong fields (".scalar(@i).")");
             debug("Anomaly in loaddb(); line $. of $opts->{dbfile} has wrong ".
@@ -274,6 +274,8 @@ sub loaddb { # load the players database
         $rps->{$i[0]}{pen_quest},
         $rps->{$i[0]}{pen_logout},
         $rps->{$i[0]}{pen_title},
+        $rps->{$i[0]}{pen_align},
+        $rps->{$i[0]}{pen_class},
         $rps->{$i[0]}{created},
         $rps->{$i[0]}{lastlogin},
         $rps->{$i[0]}{item}{amulet},
@@ -339,6 +341,8 @@ sub writedb {
                         "pen_quest",
                         "pen_logout",
                         "pen_title",
+                        "pen_align",
+                        "pen_class",
                         "created",
                         "last login",
                         "amulet",
@@ -387,6 +391,8 @@ sub writedb {
                                 $rps->{$k}{pen_quest},
                                 $rps->{$k}{pen_logout},
                                 $rps->{$k}{pen_title},
+                                $rps->{$k}{pen_align},
+                                $rps->{$k}{pen_class},
                                 $rps->{$k}{created},
                                 $rps->{$k}{lastlogin},
                                 $rps->{$k}{item}{amulet},
@@ -473,7 +479,8 @@ sub createdb {
     }
     for my $pen ("pen_mesg","pen_nick","pen_part",
                  "pen_kick","pen_quit","pen_quest",
-                 "pen_logout","pen_logout","pen_title") {
+                 "pen_logout","pen_logout","pen_title",
+			 	 "pen_align","pen_class") {
         $rps{$uname}{$pen} = 0;
     }
     writedb(\%rps);
-- 
GitLab