Skip to content

Commit

Permalink
feat(content): finish main quest_chompybird (#797)
Browse files Browse the repository at this point in the history
* refactor(content): use queues for eating toad

* feat(content): set varp after chompy eats toad

* feat(content): rantz shoots at chompies

* feat(content): specific message for magic on chompy bird

* fix(content): set bugs/fycie flavour varbits properly

* feat(content): chompybird combat

* feat: chompybird kill tracking

* fix(content): line breaks

* fix(content): remove rantz/bugs/fycie ingredients

* feat(content): add npc_anim command

* fix(content): use correct completion dialog

* fix(engine): add `active_player`/`active_player2` pointers to `p_finduid`
  • Loading branch information
Jameskmonger authored Aug 25, 2024
1 parent 567e395 commit 4d9845f
Show file tree
Hide file tree
Showing 12 changed files with 299 additions and 24 deletions.
12 changes: 12 additions & 0 deletions data/src/scripts/_test/scripts/engine/debug_npc.rs2
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,15 @@ if (npc_find(coord, $npc, 5, 0) = true) {
} else {
mes("No NPC found");
}

[debugproc,npc_anim](npc $npc, seq $seq)
if ($npc = null | $seq = null) {
@debugusage("::npc_anim (name) (op)", "::npc_anim chompy_bird chompy_walk", "");
return;
}

if (npc_find(coord, $npc, 5, 0) = true) {
npc_anim($seq, 0);
} else {
mes("No NPC found");
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ head1=model_141_npc_head
wanderrange=2
param=death_anim,ogre_death
param=death_sound,giant_death
timer=5

[chompybird_fycie]
vislevel=hide
Expand Down Expand Up @@ -82,10 +83,14 @@ op5=Attack
vislevel=6
model1=model_3445_obj
param=attack_sound,chompy_bird_attack
param=attack_anim,seq_1012
param=defend_sound,chompy_bird_hit
param=defend_anim,seq_1011
param=death_sound,chompy_bird_death
param=death_anim,seq_1009
// TODO tbc
huntrange=10
hitpoints=10

[chompy_bird_corpse]
vislevel=hide
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[quest_chompybird_baiter]
type=player_uid
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mes("You release the toad and see it hop off into the distance.");

[opheld1,bloated_toad]
if (%chompybird_progress < ^chompybird_shown_toad) {
// TODO confirm line breaks, currently overruns
~objbox(bloated_toad,"You're not sure where Rantz told you to place the bloated toad. You decide to wait and ask him where to place it.");
return;
}
Expand Down Expand Up @@ -41,6 +42,7 @@ p_delay(0);

if (p_finduid(uid) = true) {
npc_add(coord, bloated_toad, 101);
%quest_chompybird_baiter = uid;
npc_queue(4, 0, 25);

mes("You carefully place the bloated toad bait.");
Expand Down Expand Up @@ -105,7 +107,7 @@ if ($toad_should_explode = true) {
}

if ($should_spawn_chompy = true) {
~spawn_chompy_bird(npc_coord);
~spawn_chompy_bird(npc_coord, %quest_chompybird_baiter);
}

[proc,toad_explode]()
Expand All @@ -120,3 +122,14 @@ while (.huntnext = true) {
// is damage random per-player or per-toad?
~.damage_self(calc(random(1) + 1));
}

// The toad is being eaten by the Chompy
[ai_queue5,bloated_toad]
npc_delay(3);

// TODO do we need to check that the Chompy is still there and eating the toad?
// should test on OSRS to confirm

npc_say("!!Croak!!");
npc_delay(2);
npc_del;
2 changes: 1 addition & 1 deletion data/src/scripts/quests/quest_chompybird/scripts/bugs.rs2
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ switch_int(%chompybird_progress) {

if ($flavour = 0) {
$flavour = calc(random(1) + 1);
setbit_range_toint(%chompybird_kills, $flavour, ^chompybird_varbit_bugs_flavour_start, ^chompybird_varbit_bugs_flavour_end);
%chompybird_kills = setbit_range_toint(%chompybird_kills, $flavour, ^chompybird_varbit_bugs_flavour_start, ^chompybird_varbit_bugs_flavour_end);
}

def_string $chompy_flavour = "equa leaves";
Expand Down
204 changes: 189 additions & 15 deletions data/src/scripts/quests/quest_chompybird/scripts/chompy_bird.rs2
Original file line number Diff line number Diff line change
@@ -1,36 +1,39 @@
[proc,spawn_chompy_bird](coord $coord)
[proc,spawn_chompy_bird](coord $coord, player_uid $baiter_uid)
{
// def_coord $spawn_coord = map_findsquare($coord, 3, 10, 1);
def_coord $spawn_coord = map_findsquare($coord, 4, 4, 1);

npc_add($spawn_coord, chompy_bird, 100);
%quest_chompybird_baiter = $baiter_uid;
// TODO anim?
npc_say("Sqwirk!");

// TODO confirm behaviour, looks like it wanders first then hunts?
npc_sethuntmode(chompybird);
}

// triggered by the .hunt config, the Chompy has found, and arrived at, the Bloated Toad
[ai_queue4,chompy_bird]
if (.npc_find(npc_coord, bloated_toad, 1, 1) = true) {
// TODO get delays, anims etc with OSRS
npc_say("Sqwark!");
npc_sethuntmode(null);
npc_facesquare(.npc_coord);

.npc_delay(3);

if (npc_finduid(npc_uid) = true & .npc_finduid(.npc_uid) = true) {
.npc_say("!!Croak!!");
npc_say("Gobble!");
npc_queue(5, 0, 0);
.npc_queue(5, 0, 0);
}

.npc_delay(2);
// the Chompy is eating the toad
[ai_queue5,chompy_bird]
npc_say("Sqwark!");
npc_delay(3);
npc_say("Gobble!");
npc_delay(2);

if (.npc_finduid(.npc_uid) = true) {
.npc_del;
// TODO consider some check that the toad actually still exists?
// might not be necessary though

// TODO how to set `%chompybird_progress = ^chompybird_chompy_ate_toad` for the player who spawned the toad?
// TODO clear hunt mode?
}
if (p_finduid(%quest_chompybird_baiter) = true) {
if (%chompybird_progress = ^chompybird_dropped_toad) {
%chompybird_progress = ^chompybird_chompy_ate_toad;
}
}

Expand All @@ -42,3 +45,174 @@ obj_add(npc_coord, raw_chompy, 1, ^lootdrop_duration);
obj_add(npc_coord, bones, 1, ^lootdrop_duration);
inv_add(inv, feather, calc(random(20) + 10));
npc_del;

[apnpc5,chompy_bird]
def_obj $rhand = inv_getobj(worn, ^wearpos_rhand);

// make the player run to the bird if they are unarmed
if ($rhand = null)
{
p_aprange(1);
return;
}

def_category $rhand_cat = oc_category($rhand);

// make the player run to the bird if they have a melee weapon equipped
if ($rhand_cat = weapon_slash
| $rhand_cat = weapon_stab
| $rhand_cat = weapon_axe
| $rhand_cat = weapon_pickaxe
| $rhand_cat = weapon_blunt
| $rhand_cat = weapon_spear
| $rhand_cat = weapon_spiked
| $rhand_cat = weapon_2h_sword
| $rhand_cat = weapon_staff
| $rhand_cat = weapon_scythe)
{
p_aprange(1);
return;
}

// otherwise start combat from a distance
@player_combat_chompybird_start;

[opnpc5,chompy_bird]
@player_combat_chompybird_start;

[label,player_combat_chompybird_start]
def_obj $rhand = inv_getobj(worn, ^wearpos_rhand);

if ($rhand = null)
{
// TODO confirm for 2004
mes("You'll need a weapon to try and attack this beast.");
return;
}

def_category $rhand_cat = oc_category($rhand);

if ($rhand_cat = weapon_slash
| $rhand_cat = weapon_stab
| $rhand_cat = weapon_axe
| $rhand_cat = weapon_pickaxe
| $rhand_cat = weapon_blunt
| $rhand_cat = weapon_spear
| $rhand_cat = weapon_spiked
| $rhand_cat = weapon_2h_sword
| $rhand_cat = weapon_staff
| $rhand_cat = weapon_scythe)
{
// TODO confirm for 2004
mes("The Chompy Bird is too quick for your melee weapon.");
return;
}

if (
$rhand ! ogre_bow
& (
$rhand_cat = weapon_bow
| $rhand_cat = weapon_crossbow
| $rhand_cat = weapon_thrown
| $rhand_cat = weapon_javelin))
{
// TODO confirm for 2004
mes("Your ranged weapon isn't powerful enough to hurt the Chompy bird.");
return;
}


def_obj $ammo = inv_getobj(worn, ^wearpos_quiver);
if ($ammo = null) {
// TODO confirm for 2004
mes("There is no ammo left in your quiver.");
return;
}

if ($ammo ! ogre_arrow) {
// TODO confirm for 2004
mes("You can't use that ammo with your bow.");
return;
}

~player_combat_chompybird($rhand, $ammo);

// is this right? it's basically a replica of the existing combat logic,
// but that relies on some npc_hasop(2) checks, which I don't want to mess with
[proc,player_combat_chompybird](obj $rhand, obj $ammo)
def_int $distance = npc_range(coord);
def_int $attackrange = min(oc_param($rhand, attackrange), 10);
if (%damagestyle = ^style_ranged_longrange) {
$attackrange = min(add($attackrange, 2), 10);
}

if (($attackrange <= 1 & ~player_in_combat_check = false) | $distance > $attackrange) {
// p_opnpc(2);
p_aprange($attackrange);
return;
}

p_stopaction;
// npc_setmode(opplayer2);
// facesquare(npc_coord);

if (%action_delay > map_clock | getwalktrigger() = stunned) {
p_opnpc(2);
return;
}

~player_combat_stat; // update combat varps before calculating action_delay and shooting

// set the skill clock depending on the weapon attack rate
%action_delay = add(map_clock, oc_param($rhand, attackrate));

if (%damagestyle = ^style_ranged_rapid) {
%action_delay = sub(%action_delay, 1);
}

// check hit, give combat xp
def_int $damage = 0;
if (~player_npc_hit_roll(%damagetype) = true) {
$damage = randominc(min(%com_maxhit, npc_param(max_dealt)));
$damage = min($damage, npc_stat(hitpoints));
~give_combat_experience(%damagestyle, $damage, npc_param(combat_xp_multiplier));
}

def_int $delay = add(~player_ranged_use_weapon($rhand, $ammo), 30); // osrs it seems to be delayed an extra tick
anim(%com_attackanim, 0);
sound_synth(%com_attacksound, 0, 0);
~npc_retaliate(calc($delay / 30));
npc_queue(2, $damage, calc($delay / 30));
npc_anim(npc_param(defend_anim), sub($delay, 30)); // delay npc this tick
if (npc_param(defend_sound) ! null) {
sound_synth(npc_param(defend_sound), 0, sub($delay, 30)); // delay 1 client tick for the hit queue
}

npc_heropoints($damage);

p_opnpc(2);
if (random(5) ! 0) {
world_delay(calc($delay / 30 - 2));
if (map_blocked(npc_coord) = false) {
if (p_finduid(uid) = true) {
inv_dropslot(ranged_quiver_inv, npc_coord, 0, 200);
}
}
}
inv_clear(ranged_quiver_inv);

[ai_queue3,chompy_bird]
gosub(npc_death);

if(npc_findhero = true) {
queue(chompybird_kill, 0);
}

// TODO confirm duration
npc_add(npc_coord, chompy_bird_corpse, 100);

[queue,chompybird_kill]
if (%chompybird_progress = ^chompybird_rantz_gave_player_bow) {
%chompybird_progress = ^chompybird_player_killed_chompy;
}
// TODO add chompy bird killcount
4 changes: 2 additions & 2 deletions data/src/scripts/quests/quest_chompybird/scripts/fycie.rs2
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ switch_int(%chompybird_progress) {
return;
}

~chatnpc("<p,neutral>Hey you Creature, I know's what you is You's a 'uman!");
~chatnpc("<p,neutral>Hey you Creature, I know's what you is You's a|'uman!");
~chatplayer("<p,happy>That's right... I'm making some 'stabbers' for Rantz.");
~chatnpc("<p,default>Dat's great...Dad want's to hunt da chompy... Da chompy is our bestest yumms! Yous needies da scratchers for makin' dem huh? I's wants some bright pretties for em!");

Expand Down Expand Up @@ -50,7 +50,7 @@ switch_int(%chompybird_progress) {

if ($flavour = 0) {
$flavour = calc(random(1) + 1);
setbit_range_toint(%chompybird_kills, $flavour, ^chompybird_varbit_fycie_flavour_start, ^chompybird_varbit_fycie_flavour_end);
%chompybird_kills = setbit_range_toint(%chompybird_kills, $flavour, ^chompybird_varbit_fycie_flavour_start, ^chompybird_varbit_fycie_flavour_end);
}

def_string $chompy_flavour = "tomato";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,4 @@ stat_advance(fletching, 262);
stat_advance(cooking, 1470);
stat_advance(ranged, 735);
// TODO is ogre bow given separately here?
// TODO confirm completion dialog
~send_quest_complete(questlist:chompybird, ogre_bow, 250, ^chompybird_questpoints, "You have completed Big Chompy Bird Hunting!");
~send_quest_complete(questlist:chompybird, ogre_bow, 250, ^chompybird_questpoints, "You have completed the 'Chompy Bird' Quest!");
39 changes: 38 additions & 1 deletion data/src/scripts/quests/quest_chompybird/scripts/rantz.rs2
Original file line number Diff line number Diff line change
Expand Up @@ -329,5 +329,42 @@ queue(quest_chompybird_complete, 0);
~objbox(seasoned_chompy, "You hand over the cooked chompy bird to Rantz.");

~chatnpc("<p,neutral>Hey hey! We got da delicious chompy bird - yay!|This looks really tasty as well!");
~chatnpc("<p,neutral>Tank's very much for da chompy...|Fycie an Bugs like very much da chompy yumms!|@dbl@~ The family of ogres sit down together and enjoy your well cooked chompy bird. ~");
~chatnpc("<p,neutral>Tank's very much for da chompy...|Fycie an Bugs like very much da chompy yumms!|@dbl@~ The family of ogres sit down together and enjoy|@dbl@your well cooked chompy bird. ~");
~chatplayer("<p,neutral>It's my pleasure!");

// look for any chompy birds to shoot
[ai_timer,chompybird_rantz]
.npc_findallany(npc_coord, 24, 0);
while (.npc_findnext = true) {
// find any chompy birds close to Rantz
if (.npc_type = chompy_bird) {
if (p_finduid(.%quest_chompybird_baiter) = true) {
// we only run this logic for players in the right quest state
if (%chompybird_progress = ^chompybird_chompy_ate_toad) {
// TODO fix the delays in this section

// TODO send mesbox if player is close?
// not sure which one was in 04
mes("Rantz: Hey, dere's da chompy, I's gonna shoot it.");
npc_facesquare(.npc_coord);

// npc_delay(1);

npc_anim(ogre_attackbow, 0);
spotanim_npc(ogre_arrow_launch, 50, 0);
def_int $duration = ~npc_projectile(npc_coord, .npc_uid, ogre_arrow_travel, 40, 36, 41, 15, 5, 11, 5);
// def_int $delay = add(sub(divide($duration, 30), 1), 2);

// npc_delay($delay);

if (p_finduid(.%quest_chompybird_baiter) = true) {
%chompybird_progress = ^chompybird_rantz_tried_to_shoot_chompy;
// TODO send mesbox if player is close?
// not sure which one was in 04
mes("Rantz keeps missing the chompy bird...");
mes("Rantz: Grrr...de'ese arrows are rubbish.");
}
}
}
}
}
Loading

0 comments on commit 4d9845f

Please sign in to comment.