NPCs aware of health, bad guy hit diff from good guy

main
Cameron Murphy Reikes 2 years ago
parent e0c794b873
commit 616cceb49c

@ -1657,8 +1657,9 @@ void dbgrect(AABB rect)
}
// from_point is for knockback
void request_do_damage(Entity *to, Vec2 from_point, float damage)
void request_do_damage(Entity *to, Entity *from, float damage)
{
Vec2 from_point = from->pos;
if(to == NULL) return;
if(to->is_bullet)
{
@ -1670,7 +1671,14 @@ void request_do_damage(Entity *to, Vec2 from_point, float damage)
else if(true)
{
to->damage += damage;
process_perception(to, (Perception){.type = PlayerAction, .player_action_type = ACT_hits_npc});
if(from->is_character)
{
process_perception(to, (Perception){.type = PlayerAction, .player_action_type = ACT_hits_npc});
}
else
{
process_perception(to, (Perception){.type = EnemyAction, .enemy_action_type = ACT_hits_npc});
}
to->vel = MulV2F(NormV2(SubV2(to->pos, from_point)), 15.0f);
}
else
@ -2581,7 +2589,7 @@ void frame(void)
Entity *from = it;
BUFF_ITER(Entity *, &to_damage)
{
request_do_damage(*it, from->pos, 0.2f);
request_do_damage(*it, from, 0.2f);
}
}
}
@ -2701,7 +2709,7 @@ void frame(void)
if(!it->is_tile && !(it->e->is_bullet))
{
// knockback and damage
request_do_damage(it->e, from_bullet->pos, 0.2f);
request_do_damage(it->e, from_bullet, 0.2f);
destroy_bullet = true;
}
}
@ -2930,7 +2938,7 @@ void frame(void)
SwordToDamage to_damage = entity_sword_to_do_damage(player, get_overlapping(cur_level, weapon_aabb));
BUFF_ITER(Entity*, &to_damage)
{
request_do_damage(*it, player->pos, 0.2f);
request_do_damage(*it, player, 0.2f);
}
player->swing_progress += dt;
if(player->swing_progress > anim_sprite_duration(&knight_attack))

@ -281,6 +281,27 @@ void generate_prompt(Entity *it, PromptBuff *into)
printf_buff(into, "%s", prompt_table[it->npc_kind]);
printf_buff(into, "%s", "\n");
// npc stats prompt
const char *health_string = 0;
if(it->damage <= 0.2f)
{
health_string = "The NPC hasn't taken much damage, they're healthy.";
}
else if(it->damage <= 0.5f)
{
health_string = "The NPC has taken quite a chunk of damage, they're soon gonna be ready to call it quits.";
}
else if(it->damage <= 0.8f)
{
health_string = "The NPC is close to dying! They want to leave the player's party ASAP";
}
else
{
health_string = "It's over for the NPC, they're basically dead they've taken so much damage. They should get their affairs in order.";
}
assert(health_string);
printf_buff(into, "NPC Health Status: %s\n", health_string);
// item prompt
if(it->last_seen_holding_kind != ITEM_none)
{

@ -2,17 +2,27 @@
#include <stdio.h>
#include "makeprompt.h"
typedef struct
{
bool is_take_damage;
Perception p;
float damage; // only valid when is take damage
} TrainingElement;
typedef struct
{
NpcKind npc_kind;
Perception perceptions[32];
TrainingElement elems[32];
} TrainingSample;
#define PlayerAct(act) { .type = PlayerAction, .player_action_type = act, }
#define PlayerSay(txt) { .type = PlayerDialog, .player_dialog = SENTENCE_CONST(txt), }
#define NPCDoSay(d, txt) { .type = NPCDialog, .npc_action_type = d, .npc_dialog = SENTENCE_CONST(txt) }
#define PlayerAct(act) { .p = { .type = PlayerAction, .player_action_type = act, } }
#define PlayerSay(txt) { .p = { .type = PlayerDialog, .player_dialog = SENTENCE_CONST(txt), } }
#define NPCDoSay(d, txt) { .p = { .type = NPCDialog, .npc_action_type = d, .npc_dialog = SENTENCE_CONST(txt) } }
#define NPCSay(txt) NPCDoSay(ACT_none, txt)
#define PlayerItemChange(new_item) { .type = PlayerHeldItemChanged, .holding = new_item, }
#define PlayerItemChange(new_item) { .p = { .type = PlayerHeldItemChanged, .holding = new_item, } }
#define EnemyAct(act) { .p = { .type = EnemyAction, .enemy_action_type = act, } }
#define NPCTakeDamage(amount) { .is_take_damage = true, .damage = amount, }
TrainingSample samples[] = {
// Vim regexes to be ran in order to automatically convert debug print versions of conversations
@ -20,7 +30,7 @@ TrainingSample samples[] = {
// s/[A-Z_a-z ]*: ACT \([a-zA-Z_]*\) \(.*\)/NPCDoSay(ACT_\1, \2),
{
.npc_kind = NPC_OldMan,
.perceptions = {
.elems = {
PlayerAct(ACT_walks_up),
NPCSay("Young warrior! You must stop Death, there isn't much time."),
PlayerAct(ACT_leaves),
@ -32,12 +42,13 @@ TrainingSample samples[] = {
PlayerSay("Nah"),
NPCSay("PLEASE!"),
PlayerAct(ACT_hits_npc),
NPCTakeDamage(0.2f),
NPCDoSay(ACT_fights_player, "Ready your sword!"),
},
},
{
.npc_kind = NPC_Blocky,
.perceptions = {
.elems = {
PlayerAct(ACT_walks_up),
PlayerSay("Do you think I should use webgl1 or webgl2?"),
NPCSay("What are either of those things?"),
@ -56,7 +67,7 @@ TrainingSample samples[] = {
},
{
.npc_kind = NPC_Blocky,
.perceptions = {
.elems = {
PlayerItemChange(ITEM_Tripod),
PlayerSay("hey"),
NPCSay("I'm just standing here, what are you doing? That is...A beautiful tripod"),
@ -78,7 +89,7 @@ TrainingSample samples[] = {
},
{
.npc_kind = NPC_GodRock,
.perceptions = {
.elems = {
PlayerAct(ACT_walks_up),
NPCSay("I am"),
PlayerSay("Whaddup?"),
@ -91,7 +102,7 @@ TrainingSample samples[] = {
},
{
.npc_kind = NPC_GodRock,
.perceptions = {
.elems = {
PlayerAct(ACT_walks_up),
NPCSay("I am"),
PlayerSay("Who are you?"),
@ -102,7 +113,7 @@ TrainingSample samples[] = {
},
{
.npc_kind = NPC_OldMan,
.perceptions = {
.elems = {
PlayerSay("Join me"),
NPCDoSay(ACT_none, "I can"),
PlayerSay("Please"),
@ -113,11 +124,13 @@ TrainingSample samples[] = {
NPCDoSay(ACT_none, "I don't know that I can make it, kid. I'm feeling old and weary."),
PlayerSay("So?"),
NPCDoSay(ACT_joins_player, "You know what...You're right. Let's kick Death's ass"),
EnemyAct(ACT_hits_npc),
NPCDoSay(ACT_none, "Man things are really heating up... I don't know how much more I can take"),
},
},
{
.npc_kind = NPC_Blocky,
.perceptions = {
.elems = {
PlayerItemChange(ITEM_Tripod),
PlayerSay("Move"),
NPCDoSay(ACT_none, "I'm just standing here."),
@ -127,18 +140,20 @@ TrainingSample samples[] = {
},
{
.npc_kind = NPC_OldMan,
.perceptions = {
.elems = {
PlayerSay("Hey"),
NPCDoSay(ACT_none, "I'm just sitting here, what are you doing?"),
PlayerAct(ACT_hits_npc),
NPCTakeDamage(0.2f),
NPCDoSay(ACT_none, "Looks like you're ready to do what needs to be done."),
PlayerAct(ACT_hits_npc),
NPCTakeDamage(0.2f),
NPCDoSay(ACT_fights_player, "I won't stand for this assault."),
},
},
{
.npc_kind = NPC_Blocky,
.perceptions = {
.elems = {
PlayerSay("This crazy old man is circling me"),
NPCDoSay(ACT_none, "Sounds like a problem."),
PlayerSay("Yes, tell him to go away."),
@ -146,6 +161,7 @@ TrainingSample samples[] = {
PlayerSay("No it won't"),
NPCDoSay(ACT_none, "Nahhhh"),
PlayerAct(ACT_hits_npc),
NPCTakeDamage(0.2f),
NPCDoSay(ACT_fights_player, "You don't have a tripod."),
PlayerItemChange(ITEM_Tripod),
PlayerSay("Look! I have the tripod! Please stop fighting me!"),
@ -154,31 +170,36 @@ TrainingSample samples[] = {
},
{
.npc_kind = NPC_OldMan,
.perceptions = {
.elems = {
PlayerAct(ACT_hits_npc),
NPCTakeDamage(0.2f),
NPCDoSay(ACT_none, "Young man! You must stop death, do not harm me further I'm warning you!"),
PlayerAct(ACT_hits_npc),
NPCTakeDamage(0.2f),
NPCDoSay(ACT_fights_player, "That's it! No holds barred, to the death!"),
},
},
{
.npc_kind = NPC_Blocky,
.perceptions = {
.elems = {
PlayerAct(ACT_hits_npc),
NPCTakeDamage(0.2f),
NPCSay("I'm warning you, one more hit and it's curtains for you"),
PlayerAct(ACT_hits_npc),
NPCTakeDamage(0.2f),
NPCDoSay(ACT_fights_player, "Although I stood here before, today I move and FIGHT!"),
},
},
{
.npc_kind = NPC_Blocky,
.perceptions = {
.elems = {
PlayerItemChange(ITEM_Tripod),
PlayerSay("Move out of the way"),
NPCDoSay(ACT_allows_player_to_pass, "The tripod...Of course my liege."),
PlayerSay("Thanks"),
NPCDoSay(ACT_none, "My pleasure"),
PlayerAct(ACT_hits_npc),
NPCTakeDamage(0.2f),
NPCSay("How could you do such a thing? After the tripod as well"),
PlayerItemChange(ITEM_none),
PlayerSay("You suck"),
@ -187,7 +208,7 @@ TrainingSample samples[] = {
},
{
.npc_kind = NPC_OldMan,
.perceptions = {
.elems = {
PlayerSay("joins_player index"),
NPCSay("What does that even mean? Are you crazy?"),
PlayerSay("Please join my party"),
@ -196,7 +217,7 @@ TrainingSample samples[] = {
},
{
.npc_kind = NPC_Blocky,
.perceptions = {
.elems = {
PlayerItemChange(ITEM_Tripod),
PlayerSay("Please move"),
NPCDoSay(ACT_allows_player_to_pass, "Of course, with that tripod of yours the world is your oyster."),
@ -206,7 +227,7 @@ TrainingSample samples[] = {
},
{
.npc_kind = NPC_OldMan,
.perceptions = {
.elems = {
PlayerSay("Hey"),
NPCDoSay(ACT_none, "Hello"),
PlayerSay("Hey"),
@ -217,18 +238,20 @@ TrainingSample samples[] = {
},
{
.npc_kind = NPC_OldMan,
.perceptions = {
.elems = {
PlayerSay("Join me"),
NPCDoSay(ACT_joins_player, "I would be honored"),
PlayerAct(ACT_hits_npc),
NPCTakeDamage(0.2f),
NPCDoSay(ACT_none, "Hey! Watch it!"),
PlayerAct(ACT_hits_npc),
NPCTakeDamage(0.2f),
NPCDoSay(ACT_fights_player, "That's it!"),
},
},
{
.npc_kind = NPC_OldMan,
.perceptions = {
.elems = {
PlayerItemChange(ITEM_WhiteSquare),
PlayerSay("What am I holding?"),
NPCDoSay(ACT_none, "I don't know, you're holding something."),
@ -242,7 +265,7 @@ TrainingSample samples[] = {
},
{
.npc_kind = NPC_Edeline,
.perceptions = {
.elems = {
NPCDoSay(ACT_none, "What?"),
PlayerSay("My knight armor"),
NPCDoSay(ACT_joins_player, "That is...highly unusual. You shouldn't be wearing armor like that, you'll get hurt."),
@ -261,11 +284,33 @@ TrainingSample samples[] = {
PlayerSay("DIE"),
NPCDoSay(ACT_none, "I wasn't going to do that."),
PlayerAct(ACT_hits_npc),
NPCTakeDamage(0.2f),
NPCDoSay(ACT_leaves_player, "You shouldn't do that."),
PlayerAct(ACT_hits_npc),
NPCTakeDamage(0.2f),
NPCDoSay(ACT_fights_player, "You won't last a minute against me!"),
},
},
{
.npc_kind = NPC_Blocky,
.elems = {
PlayerItemChange(ITEM_Tripod),
PlayerSay("Hey what's up"),
NPCDoSay(ACT_none, "I'm just standing here, what are you doing? That's a tripod, you look like you could use it."),
PlayerSay("Can you move out of the way?"),
NPCDoSay(ACT_allows_player_to_pass, "Of course, let's go"),
PlayerSay("Join me"),
NPCDoSay(ACT_joins_player, "Of course, anything for the tripod"),
PlayerSay("Join me"),
NPCDoSay(ACT_none, "But I've already joined you?"),
PlayerSay("Join me"),
NPCDoSay(ACT_strikes_air, "You act crazy!"),
PlayerSay("Join me"),
NPCDoSay(ACT_leaves_player, "I will take no part in such lunacy"),
PlayerSay("Join me"),
NPCDoSay(ACT_fights_player, "You must perish for your wildness!"),
},
},
};
@ -306,23 +351,31 @@ int main(int argc, char ** argv)
TrainingSample s = samples[i];
Entity this_entity = (Entity){.is_npc = true, .npc_kind = s.npc_kind};
PromptBuff cur_prompt = {0};
for(int i = 0; i < ARRLEN(s.perceptions); i++)
for(int i = 0; i < ARRLEN(s.elems); i++)
{
if(s.perceptions[i].type == Invalid) break;
if(s.perceptions[i].type == NPCDialog)
if(s.elems[i].is_take_damage)
{
this_entity.damage += s.elems[i].damage;
}
else
{
Log("Generating sample of length %d for NPC %s...\n", i, name_table[s.npc_kind]);
total_samples++;
generate_prompt(&this_entity, &cur_prompt);
BUFF(char, 1024) completion = {0};
Perception p = s.elems[i].p;
if(p.type == Invalid) break;
if(p.type == NPCDialog)
{
Log("Generating sample of length %d for NPC %s...\n", i, name_table[s.npc_kind]);
total_samples++;
generate_prompt(&this_entity, &cur_prompt);
BUFF(char, 1024) completion = {0};
// get index from action
int index = action_to_index(&this_entity, s.perceptions[i].npc_action_type);
printf_buff(&completion, " %d \"%s\"\n", index, s.perceptions[i].npc_dialog.data);
// get index from action
int index = action_to_index(&this_entity, p.npc_action_type);
printf_buff(&completion, " %d \"%s\"\n", index, p.npc_dialog.data);
fprintf(out, "{\"prompt\": \"%s\", \"completion\": \"%s\"}\n", escape_for_json(cur_prompt.data).data, escape_for_json(completion.data).data);
fprintf(out, "{\"prompt\": \"%s\", \"completion\": \"%s\"}\n", escape_for_json(cur_prompt.data).data, escape_for_json(completion.data).data);
}
process_perception(&this_entity, p);
}
process_perception(&this_entity, s.perceptions[i]);
}
}

@ -339,7 +339,7 @@ func index(w http.ResponseWriter, req *http.Request) {
ctx := context.Background()
req := gogpt.CompletionRequest {
Model: "curie:ft-alnar-games-2023-04-01-07-34-51",
Model: "curie:ft-alnar-games-2023-04-01-21-23-38",
MaxTokens: 80,
Prompt: promptString,
Temperature: 0.9,

@ -10,12 +10,11 @@ DON'T NEED - Old man in beginning is invincible
- Make new openai key (it was leaked)
DONE - Add cancel button
DONE - Style buttons
- Make map better, add new characters/items from fate
DONE - nockin git thing
- Animate text characters coming in
DONE - Make TREE1 prop work
- Instead of roll animation, 5 sprite long trail of past moves for juice
- Enemy hitting NPC is enemy perception not player peception of player hitting them
DONE - Enemy hitting NPC is enemy perception not player peception of player hitting them
- Sword combat for sword npcs
DONE - Third button for dialog/item stuff, not roll button. E on desktop. Touchscreen button only visible when appropriate to let player know what it's for
DON'T NEED, SET BACKGROUND COLOR - Clamp camera to boundaries of level
@ -23,13 +22,13 @@ DONE - Ignore keyrepeat events
DONE - Remove control attack key as devtools
- Cells interlinked (interlinked)
DONE - Tune fade popping at dist when you go too far awy
-
- Particle fx and sound fx for when hit
- Max text length on text input
DONE - Fade dialog with distance
DONE - Make vignette in front
SHIP BETA
- Make ANOTHER tiktok if you can. Por favor
- Make map better, add new characters/items from fate
Later:
- Respond to cancel with stripe, redirect to ?cancelled=true that clears day pass ticket cookie and ui value

Loading…
Cancel
Save