Compare commits

...

3 Commits

Author SHA1 Message Date
wrk 14b171b1c3 hall of fame only on deathmatches 2023-06-10 02:06:37 +02:00
wrk 69fab9980c rng sleeps + shit + ideas 2023-06-10 02:02:56 +02:00
wrk 39364e6403 Deathmatches! 2023-06-09 23:59:45 +02:00
2 changed files with 300 additions and 79 deletions

7
IDEAS Normal file
View File

@ -0,0 +1,7 @@
make this fuckin lib async so I can sleep in between shit
,titlefight where looser gets 5k'd
@acidvegas │ 1000 chat lines = increased attack
@acidvegas │ 24 hour idling makes you WEAKER
@acidvegas │ > fighter of the week every friday night
@acidvegas │ > loser of the week (most deaths)
taunting on ,challenge

View File

@ -3,7 +3,7 @@ use std::{
fs::File, fs::File,
io::{Read, Write}, io::{Read, Write},
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
time::Duration, time::{Duration, SystemTime},
}; };
use ircie::{ use ircie::{
@ -11,7 +11,7 @@ use ircie::{
irc_command::IrcCommand, irc_command::IrcCommand,
system::IntoResponse, system::IntoResponse,
system_params::{AnyArguments, Arguments, Channel, Context, Res, ResMut}, system_params::{AnyArguments, Arguments, Channel, Context, Res, ResMut},
Irc, Irc, IrcPrefix,
}; };
use itertools::Itertools; use itertools::Itertools;
use rand::{ use rand::{
@ -107,6 +107,7 @@ const COLORS: &'static [&'static Color] = &[
&Color::Teal, &Color::Teal,
]; ];
#[derive(Clone)]
struct Fighter { struct Fighter {
nick: String, nick: String,
health: f32, health: f32,
@ -195,14 +196,17 @@ impl Default for Fighter {
enum FightKind { enum FightKind {
#[default] #[default]
Duel, Duel,
DeathMatch,
FreeForAll, FreeForAll,
RoyalRumble,
TeamBattle, TeamBattle,
} }
#[derive(Default, PartialEq, Eq)] #[derive(Default, Clone, PartialEq, Eq)]
enum FightStatus { enum FightStatus {
Happening, Happening,
WaitingWho, WaitingWho,
WaitingChallengee(String, SystemTime),
#[default] #[default]
Idle, Idle,
} }
@ -212,9 +216,20 @@ struct Fight {
status: FightStatus, status: FightStatus,
channel: String, channel: String,
kind: FightKind, kind: FightKind,
challengee: Option<String>,
fighters: Vec<Fighter>, fighters: Vec<Fighter>,
} }
impl Fight {
pub fn reset(&mut self) {
self.status = FightStatus::Idle;
self.channel = "".to_owned();
self.kind = FightKind::Duel;
self.challengee = None;
self.fighters.clear();
}
}
#[tokio::main] #[tokio::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
env_logger::init(); env_logger::init();
@ -227,16 +242,20 @@ async fn main() -> std::io::Result<()> {
.await .await
.add_resource(HallOfFame::load(SAVE_LOC).unwrap()) .add_resource(HallOfFame::load(SAVE_LOC).unwrap())
.await .await
.add_interval_task(Duration::from_secs(1), fight) .add_interval_task(Duration::from_millis(10), fight)
.await .await
.add_event_system(IrcCommand::RPL_WHOREPLY, whoreply) .add_event_system(IrcCommand::RPL_WHOREPLY, whoreply)
.await .await
.add_event_system(IrcCommand::RPL_ENDOFWHO, start_rumble) .add_event_system(IrcCommand::RPL_ENDOFWHO, endofwho)
.await .await
.add_system("f", new_fight) .add_system("f", new_fight)
.await .await
.add_system("royalrumble", royal_rumble) .add_system("royalrumble", royal_rumble)
.await .await
.add_system("challenge", challenge)
.await
.add_system("accept", accept_challenge)
.await
.add_system("hof", show_hall_of_fame) .add_system("hof", show_hall_of_fame)
.await .await
.add_system("h", show_help) .add_system("h", show_help)
@ -256,8 +275,25 @@ fn fight(
mut rng: ResMut<StdRng>, mut rng: ResMut<StdRng>,
mut hall_of_fame: ResMut<HallOfFame>, mut hall_of_fame: ResMut<HallOfFame>,
) { ) {
if let FightStatus::WaitingChallengee(nick, time) = &fight.status {
if let Ok(elapsed) = time.elapsed() {
if elapsed.as_secs() > 30 {
ctx.privmsg(
&fight.channel,
&Msg::new()
.color(Color::Yellow)
.text(&format!("{} pussied out.", nick))
.to_string(),
);
fight.reset();
return;
}
}
}
if fight.status != FightStatus::Happening { if fight.status != FightStatus::Happening {
std::thread::sleep(Duration::from_millis(50)); std::thread::sleep(Duration::from_millis(500));
return; return;
} }
@ -279,38 +315,53 @@ fn fight(
.filter(|f| f.team_idx == team_idx) .filter(|f| f.team_idx == team_idx)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mut lines = vec![];
if fight.fighters.len() == 1 { if fight.fighters.len() == 1 {
lines.push( ctx.privmsg(
Msg::new() &fight.channel,
&Msg::new()
.color(Color::Yellow) .color(Color::Yellow)
.text("We have a winner! -> ") .text("We have a winner! -> ")
.color(winners[0].color) .color(winners[0].color)
.text(&winners[0].nick) .text(&winners[0].nick)
.color(Color::Yellow) .color(Color::Yellow)
.text(" <- !"), .text(" <- !")
.to_string(),
); );
hall_of_fame.add_winner(&winners[0].nick); if fight.kind == FightKind::DeathMatch {
hall_of_fame.add_winner(&winners[0].nick);
}
} else { } else {
lines.push(Msg::new().color(Color::Yellow).text("We have winners!")); ctx.privmsg(
&fight.channel,
&Msg::new()
.color(Color::Yellow)
.text("We have winners!")
.to_string(),
);
for w in &winners { for w in &winners {
lines.push( ctx.privmsg(
Msg::new() &fight.channel,
&Msg::new()
.color(Color::Yellow) .color(Color::Yellow)
.text("-> ") .text("-> ")
.color(w.color) .color(w.color)
.text(&w.nick) .text(&w.nick)
.color(Color::Yellow) .color(Color::Yellow)
.text(" <-"), .text(" <-")
.to_string(),
); );
if fight.kind == FightKind::DeathMatch {
hall_of_fame.add_winner(&w.nick); hall_of_fame.add_winner(&w.nick);
}
} }
} }
for w in &winners { for w in &winners {
lines.push(Msg::new().text("!beer ").text(&w.nick)); ctx.privmsg(
&fight.channel,
&Msg::new().text("!beer ").text(&w.nick).to_string(),
);
} }
ctx.mode( ctx.mode(
@ -324,68 +375,59 @@ fn fight(
fight.fighters = vec![]; fight.fighters = vec![];
hall_of_fame.save(SAVE_LOC).unwrap(); hall_of_fame.save(SAVE_LOC).unwrap();
for line in lines {
ctx.privmsg(&fight.channel, &line.to_string())
}
fight.channel = "".to_owned(); fight.channel = "".to_owned();
return; return;
} }
let mut lines = vec![];
let body_part = BODYPARTS.choose(&mut *rng).unwrap(); let body_part = BODYPARTS.choose(&mut *rng).unwrap();
let action = ACTIONS.choose(&mut *rng).unwrap(); let action = ACTIONS.choose(&mut *rng).unwrap();
let damage = rng.gen::<f32>() * 80.; let damage = rng.gen::<f32>() * 75.;
let victim_idx = rng.gen_range(0..fight.fighters.len()); let attacker = fight.fighters.choose(&mut *rng).unwrap().clone();
let mut fucking_victim = fight.fighters.get_mut(victim_idx).unwrap(); let chan = fight.channel.clone();
if fucking_victim.nick == "wrk" { let fucking_victim = if fight
// ;)
fucking_victim = fight.fighters.get_mut(victim_idx).unwrap();
}
fucking_victim.health -= damage;
let fucking_victim = fight.fighters.get(victim_idx).unwrap();
let attacker = if fight
.fighters .fighters
.iter() .iter()
.filter(|f| f.team_idx == fucking_victim.team_idx && f.nick != fucking_victim.nick) .filter(|f| f.team_idx == attacker.team_idx && f.nick != attacker.nick)
.count() .count()
!= 0 != 0
&& rng.gen_bool(1. / 4.) && rng.gen_bool(1. / 4.)
{ {
let attacker = fight let victim = fight
.fighters .fighters
.iter() .iter_mut()
.filter(|f| f.team_idx == fucking_victim.team_idx && f.nick != fucking_victim.nick) .filter(|f| f.team_idx == attacker.team_idx && f.nick != attacker.nick)
.choose(&mut *rng) .choose(&mut *rng)
.unwrap(); .unwrap();
lines.push( ctx.privmsg(
Msg::new() &chan,
&Msg::new()
.color(Color::Yellow) .color(Color::Yellow)
.text("Oh no! ") .text("Oh no! ")
.color(attacker.color) .color(attacker.color)
.text(&attacker.nick) .text(&attacker.nick)
.color(Color::Yellow) .color(Color::Yellow)
.text(&format!(" is fucking retarded and is attacking his mate!")), .text(&format!(" is fucking retarded and is attacking his mate!"))
.to_string(),
); );
attacker victim
} else { } else {
fight fight
.fighters .fighters
.iter() .iter_mut()
.filter(|f| f.team_idx != fucking_victim.team_idx) .filter(|f| f.team_idx != attacker.team_idx)
.choose(&mut *rng) .choose(&mut *rng)
.unwrap() .unwrap()
}; };
lines.push( fucking_victim.health -= damage;
Msg::new() let fucking_victim = fucking_victim.clone();
ctx.privmsg(
&fight.channel,
&Msg::new()
.color(attacker.color) .color(attacker.color)
.text(&attacker.nick) .text(&attacker.nick)
.reset() .reset()
@ -393,25 +435,36 @@ fn fight(
.color(fucking_victim.color) .color(fucking_victim.color)
.text(&fucking_victim.nick) .text(&fucking_victim.nick)
.reset() .reset()
.text(&format!("'s {}! (-{:.2} hp)", body_part, damage)), .text(&format!("'s {}! (-{:.2} hp)", body_part, damage))
.to_string(),
); );
if fucking_victim.health <= 0. { if fucking_victim.health <= 0. {
lines.push( ctx.privmsg(
Msg::new() &fight.channel,
&Msg::new()
.color(fucking_victim.color) .color(fucking_victim.color)
.text(&fucking_victim.nick) .text(&fucking_victim.nick)
.color(Color::Yellow) .color(Color::Yellow)
.text(" is lying dead!"), .text(" is lying dead!")
.to_string(),
); );
hall_of_fame.add_fucking_looser(&fucking_victim.nick);
ctx.mode(&fight.channel, &format!("-v {}", fucking_victim.nick)); ctx.mode(&fight.channel, &format!("-v {}", fucking_victim.nick));
fight.fighters.remove(victim_idx);
}
for line in lines { if fight.kind == FightKind::DeathMatch {
ctx.privmsg(&fight.channel, &line.to_string()) hall_of_fame.add_fucking_looser(&fucking_victim.nick);
ctx.privmsg(
"ChanServ",
&format!(
"KICK {} {} {}",
fight.channel, fucking_victim.nick, "You fucking looser"
),
);
}
fight.fighters.retain(|f| f.nick != fucking_victim.nick);
} }
std::thread::sleep(Duration::from_millis(rng.gen_range(200..800)));
} }
fn new_fight( fn new_fight(
@ -420,8 +473,8 @@ fn new_fight(
mut fight: ResMut<Fight>, mut fight: ResMut<Fight>,
mut rng: ResMut<StdRng>, mut rng: ResMut<StdRng>,
) -> impl IntoResponse { ) -> impl IntoResponse {
if fight.status == FightStatus::Happening { if let Err(e) = check_idle(&fight.status) {
return Err("Shut up and watch the show".to_owned()); return Err(e);
} }
if arguments.len() < 2 { if arguments.len() < 2 {
@ -467,6 +520,7 @@ fn new_fight(
fight.fighters.push(Fighter::new(f, team_color, team_idx)); fight.fighters.push(Fighter::new(f, team_color, team_idx));
} }
} }
_ => {}
} }
fight.status = FightStatus::Happening; fight.status = FightStatus::Happening;
@ -488,6 +542,16 @@ fn new_fight(
.color(Color::Yellow) .color(Color::Yellow)
.text("Tonight's fight is a free for all!"), .text("Tonight's fight is a free for all!"),
), ),
FightKind::RoyalRumble => init_msg.push(
Msg::new()
.color(Color::Yellow)
.text("Tonight's fight is a RRRRRRROYAL RUMBLE!"),
),
FightKind::DeathMatch => init_msg.push(
Msg::new()
.color(Color::Yellow)
.text("Tonight's fight is a Death Match!"),
),
FightKind::TeamBattle => init_msg.push( FightKind::TeamBattle => init_msg.push(
Msg::new() Msg::new()
.color(Color::Yellow) .color(Color::Yellow)
@ -523,13 +587,13 @@ fn royal_rumble(
mut fight: ResMut<Fight>, mut fight: ResMut<Fight>,
mut ctx: Context, mut ctx: Context,
) -> impl IntoResponse { ) -> impl IntoResponse {
if fight.status == FightStatus::Happening { if let Err(e) = check_idle(&fight.status) {
return Err("Shut up and watch the show".to_owned()); return Err(e);
} }
fight.kind = FightKind::FreeForAll;
fight.status = FightStatus::WaitingWho; fight.status = FightStatus::WaitingWho;
fight.channel = channel.to_owned(); fight.channel = channel.to_owned();
fight.kind = FightKind::RoyalRumble;
ctx.who(&channel); ctx.who(&channel);
@ -571,6 +635,8 @@ fn show_help() -> impl IntoResponse {
",f <nick> ... vs <nick> ... | team battle", ",f <nick> ... vs <nick> ... | team battle",
",f <nick> <nick> <nick> ... | free for all", ",f <nick> <nick> <nick> ... | free for all",
",royalrumble | chan wide free for all", ",royalrumble | chan wide free for all",
",challenge <nick> | challenge someone to a deathmatch",
",accept | accept a challenge",
",s | show the current fight status", ",s | show the current fight status",
",stop | stop the current fight", ",stop | stop the current fight",
",hof | hall of fame", ",hof | hall of fame",
@ -586,26 +652,80 @@ fn show_status(fight: Res<Fight>) -> impl IntoResponse {
format!("{} fighters remaining", fight.fighters.len()) format!("{} fighters remaining", fight.fighters.len())
} }
fn stop(mut fight: ResMut<Fight>) { fn stop(prefix: IrcPrefix, mut fight: ResMut<Fight>) -> impl IntoResponse {
fight.fighters = vec![]; if fight.kind == FightKind::DeathMatch {
fight.channel = "".to_owned(); return Err("Can't stop a deathmatch");
fight.status = FightStatus::Idle; }
if prefix.nick == "sht" {
return Err("Not you you can't you grumpy nigga");
}
fight.reset();
Ok(())
} }
fn whoreply(arguments: AnyArguments, mut fight: ResMut<Fight>, mut rng: ResMut<StdRng>) { fn whoreply(
let color = COLORS.iter().choose(&mut *rng).unwrap(); arguments: AnyArguments,
let idx = fight.fighters.len();
fight
.fighters
.push(Fighter::new(arguments[5], *color.clone(), idx));
}
fn start_rumble(
mut fight: ResMut<Fight>, mut fight: ResMut<Fight>,
mut rng: ResMut<StdRng>, mut rng: ResMut<StdRng>,
mut ctx: Context, mut ctx: Context,
) -> impl IntoResponse { ) {
match fight.kind {
FightKind::DeathMatch => {
if arguments[5] != fight.challengee.as_ref().unwrap() {
return;
};
fight.status =
FightStatus::WaitingChallengee(arguments[5].to_owned(), SystemTime::now());
ctx.privmsg(
&fight.channel,
&Msg::new()
.color(Color::Yellow)
.text(format!(
"{} challenges {} to a deathmatch! you have 30s to ,accept or YOURE A BITCH",
fight.fighters[0].nick,
arguments[5]
))
.to_string(),
);
}
FightKind::RoyalRumble => {
let color = COLORS.iter().choose(&mut *rng).unwrap();
let idx = fight.fighters.len();
fight
.fighters
.push(Fighter::new(arguments[5], *color.clone(), idx));
}
_ => {}
}
}
fn endofwho(mut fight: ResMut<Fight>, rng: ResMut<StdRng>, mut ctx: Context) {
match fight.kind {
FightKind::DeathMatch => {
if fight.status == FightStatus::WaitingWho {
ctx.privmsg(
&fight.channel,
&Msg::new()
.color(Color::Yellow)
.text(format!(
"there's no {} here you stupid fuck",
fight.challengee.as_ref().unwrap()
))
.to_string(),
);
fight.reset();
return;
}
}
FightKind::RoyalRumble => start_rumble(fight, rng, ctx),
_ => {}
}
}
fn start_rumble(mut fight: ResMut<Fight>, mut rng: ResMut<StdRng>, mut ctx: Context) {
fight.status = FightStatus::Happening; fight.status = FightStatus::Happening;
let mut init_msg = vec![Msg::new() let mut init_msg = vec![Msg::new()
@ -641,3 +761,97 @@ fn start_rumble(
ctx.privmsg(&fight.channel, &line.to_string()) ctx.privmsg(&fight.channel, &line.to_string())
} }
} }
fn challenge(
prefix: IrcPrefix,
arguments: Arguments<'_, 1>,
channel: Channel,
mut fight: ResMut<Fight>,
mut ctx: Context,
mut rng: ResMut<StdRng>,
) -> impl IntoResponse {
if let Err(e) = check_idle(&fight.status) {
return Err(e);
}
fight.status = FightStatus::WaitingWho;
fight.channel = channel.to_owned();
fight.kind = FightKind::DeathMatch;
fight.challengee = Some(arguments[0].to_owned());
let color = COLORS.iter().choose(&mut *rng).unwrap();
fight
.fighters
.push(Fighter::new(prefix.nick, *color.clone(), 0));
ctx.who(&channel);
Ok(())
}
fn accept_challenge(
prefix: IrcPrefix,
_: Arguments<'_, 0>,
mut fight: ResMut<Fight>,
mut rng: ResMut<StdRng>,
) -> impl IntoResponse {
let status = fight.status.clone();
if let FightStatus::WaitingChallengee(nick, _) = status {
if nick != prefix.nick {
return Err("you haven't been challenged you stupid fuck.".to_owned());
}
let mut color = COLORS.iter().choose(&mut *rng).unwrap();
while **color == fight.fighters[0].color {
color = COLORS.iter().choose(&mut *rng).unwrap();
}
fight
.fighters
.push(Fighter::new(prefix.nick, Color::Cyan, 1));
fight.status = FightStatus::Happening;
let mut init_msg = vec![Msg::new()
.color(Color::Yellow)
.text("THE FIGHT IS ABOUT TO BEGIN! TAKE YOUR BETS!")];
init_msg.push(
Msg::new()
.color(Color::Yellow)
.text("Tonight's fight is a DEATH MATCH!"),
);
init_msg.push(
Msg::new()
.color(Color::Yellow)
.text("Everyone please welcome our contenders:"),
);
for f in &fight.fighters {
init_msg.push(
Msg::new()
.color(f.color)
.text(&f.nick)
.color(Color::Yellow)
.text("! ")
.text(PRESENTATIONS.choose(&mut *rng).unwrap()),
)
}
init_msg.push(Msg::new().color(Color::Yellow).text("TO THE DEATH!"));
return Ok((false, init_msg));
}
return Err("you haven't been challenged you stupid fuck.".to_owned());
}
fn check_idle(status: &FightStatus) -> Result<(), String> {
match status {
FightStatus::Happening => Err("Shut up and watch the show".to_owned()),
FightStatus::WaitingWho => Err("".to_owned()),
FightStatus::WaitingChallengee(_, _) => {
Err("A challenge is waiting to be accepted.".to_owned())
}
FightStatus::Idle => Ok(()),
}
}