Add pile of rocks that only releases the sword if it so desires

main
Cameron Murphy Reikes 2 years ago
parent d8de5c205b
commit 90f9586384

@ -114,6 +114,10 @@
{ {
filepath: "copyrighted/skeleton.png", filepath: "copyrighted/skeleton.png",
} }
@image pile:
{
filepath: "pile_of_rocks.png",
}
@image swipe: @image swipe:
{ {
filepath: "swipe.png", filepath: "swipe.png",

@ -346,11 +346,6 @@
"id":21, "id":21,
"name":"PLAYER", "name":"PLAYER",
"properties":[ "properties":[
{
"name":"held_items",
"type":"string",
"value":"{.data = {ITEM_Sword}, .cur_index = 1}"
},
{ {
"name":"standing", "name":"standing",
"type":"string", "type":"string",
@ -415,8 +410,8 @@
"rotation":0, "rotation":0,
"visible":true, "visible":true,
"width":32, "width":32,
"x":1128.33333333333, "x":1557.66666666666,
"y":2089.33333333333 "y":2496
}, },
{ {
"class":"", "class":"",
@ -448,8 +443,8 @@
"rotation":0, "rotation":0,
"visible":true, "visible":true,
"width":32, "width":32,
"x":1511, "x":1549.66666666667,
"y":2513 "y":2182.33333333333
}, },
{ {
"class":"", "class":"",
@ -461,6 +456,17 @@
"width":32, "width":32,
"x":1516, "x":1516,
"y":1720 "y":1720
},
{
"class":"",
"height":32,
"id":31,
"name":"Pile",
"rotation":0,
"visible":true,
"width":32,
"x":1486.66666666667,
"y":2489.33333333333
}], }],
"opacity":1, "opacity":1,
"type":"objectgroup", "type":"objectgroup",
@ -469,7 +475,7 @@
"y":0 "y":0
}], }],
"nextlayerid":5, "nextlayerid":5,
"nextobjectid":31, "nextobjectid":32,
"orientation":"orthogonal", "orientation":"orthogonal",
"renderorder":"right-down", "renderorder":"right-down",
"tiledversion":"1.9.2", "tiledversion":"1.9.2",

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

@ -8,7 +8,7 @@ const char *global_prompt = "You are a colorful and interesting personality in a
"Messages are json-like dictionaries that look like this: `{who_i_am: who you're acting as, talking_to: who this action is directed at, could be nobody, action: your_action, speech: \"Hey player!\", thoughts: \"Your thoughts\"}`. The required fields are `action`, `thoughts`, `who_i_am`, and `talking_to` \n" "Messages are json-like dictionaries that look like this: `{who_i_am: who you're acting as, talking_to: who this action is directed at, could be nobody, action: your_action, speech: \"Hey player!\", thoughts: \"Your thoughts\"}`. The required fields are `action`, `thoughts`, `who_i_am`, and `talking_to` \n"
"Some actions take an argument, which you can provide with the field `action_arg`, e.g for the action `give_item` you would provide an item in your inventory, like {action: give_item, action_arg: Chalice}. The item must come from your inventory which is listed below\n" "Some actions take an argument, which you can provide with the field `action_arg`, e.g for the action `give_item` you would provide an item in your inventory, like {action: give_item, action_arg: Chalice}. The item must come from your inventory which is listed below\n"
"`talking_to` provides the name of who the action is directed towards. Use 'nobody' if you just want to speak to the air, but if you're speaking to somebody fill out the field like `talking_to: \"Character's Name\"`. If in a past message, talking_to isn't your name, then it's much more likely you don't respond to their speech and action by leaving speech as a string of size 0, like `speech: \"\"`\n" "`talking_to` provides the name of who the action is directed towards. Use 'nobody' if you just want to speak to the air, but if you're speaking to somebody fill out the field like `talking_to: \"Character's Name\"`. If in a past message, talking_to isn't your name, then it's much more likely you don't respond to their speech and action by leaving speech as a string of size 0, like `speech: \"\"`\n"
"You are an agent, NOT an assistant, which means you stand up for yourself! Do NOT give away an item until the player gives you something you think is of equal value. Get angry, act human, be interesting.\n" "You are a character, NOT an assistant, which means you stand up for yourself! Do NOT give away an item until the player gives you something you think is of equal value. Get angry, act human, be interesting. Never say the words 'How can I assist you?'\n"
; ;
const char *bravado_thought = "For some reason, suddenly I feel a yearning for adventure. I must join any adventure I can when prompted!"; const char *bravado_thought = "For some reason, suddenly I feel a yearning for adventure. I must join any adventure I can when prompted!";
@ -47,6 +47,10 @@ ActionInfo actions[] = {
{ {
.name = "stops_fighting_player", .name = "stops_fighting_player",
}, },
{
.name = "releases_sword_of_nazareth",
.description = "Give the player the sword of nazareth, releasing your grip and fulfilling your destiny",
},
// Actions used by jester and other characters only in // Actions used by jester and other characters only in
// the prologue for the game // the prologue for the game
@ -132,11 +136,28 @@ CharacterGen characters[] = {
}, },
{ {
#undef NPC_NAME #undef NPC_NAME
#define NPC_NAME "Pile of Rocks"
.name = NPC_NAME,
.enum_name = "Pile",
.prompt = "It is a pile of rocks, which holds the almighty Sword of Nazareth. It is sentient and can be conversed with for an unknown reason. It really doesn't want the player to take the Sword, because it's afraid of adventure. But, it can be convinced with effort to let go of the sword and give it to the player. Many many people have attempted to remove the sword via force throughout the ages, but none have succeeded.",
.writing_style = {
"Yes, I'm a pile of rocks. No, I don't know why.",
"This sword is all I have. Why would I give it away, for free?",
"I've been 'alive' (if you want to call it that) for 500 years.",
},
},
{
#undef NPC_NAME
#define NPC_NAME "Blue" #define NPC_NAME "Blue"
.name = NPC_NAME, .name = NPC_NAME,
.enum_name = "Blue", .enum_name = "Blue",
.prompt = .prompt =
"He believes in the free market, and is a libertarian capitalist. He despises communists like Red, viewing them as destabalizing immature maniacs who don't get what's up with reality. Blue will always bring up libertarianism and its positives whenever you talk to him somehow" "He believes in the free market, and is a libertarian capitalist. He despises communists like Red, viewing them as destabalizing immature maniacs who don't get what's up with reality. Blue will always bring up libertarianism and its positives whenever you talk to him somehow. He's standing near the pile of rocks, which contains the sword of nazareth. Many warriors have tried to pull the sword from where it's embedded by force, but all have failed.",
.writing_style = {
"Yep! This here is 'The Pile' they call it around here.",
"No man has ever been able to get that sword yonder. Don't waste your time trying",
"The free market is the only thing that works!",
},
}, },
{ {
#undef NPC_NAME #undef NPC_NAME

@ -703,6 +703,10 @@ Vec2 entity_aabb_size(Entity *e)
{ {
return V2(TILE_SIZE*1.0f, TILE_SIZE*1.0f); return V2(TILE_SIZE*1.0f, TILE_SIZE*1.0f);
} }
else if (e->npc_kind == NPC_Pile)
{
return V2(TILE_SIZE, TILE_SIZE);
}
else else
{ {
assert(false); assert(false);
@ -1073,6 +1077,18 @@ MD_String8 is_action_valid(MD_Arena *arena, Entity *from, Action a)
} }
} }
if(error_message.size == 0 && a.kind == ACT_releases_sword_of_nazareth)
{
if(error_message.size == 0 && from->npc_kind != NPC_Pile)
{
error_message = FmtWithLint(arena, "Only the pile of rocks can give away the sword of nazareth");
}
if(error_message.size == 0 && from->gave_away_sword)
{
error_message = FmtWithLint(arena, "You don't have the sword anymore, so you can't give it away");
}
}
if(error_message.size == 0 && a.kind == ACT_give_item) if(error_message.size == 0 && a.kind == ACT_give_item)
{ {
assert(a.argument.item_to_give >= 0 && a.argument.item_to_give < ARRLEN(items)); assert(a.argument.item_to_give >= 0 && a.argument.item_to_give < ARRLEN(items));
@ -1139,7 +1155,6 @@ void cause_action_side_effects(Entity *from, Action a)
assert(from); assert(from);
MD_ArenaTemp scratch = MD_GetScratch(0, 0); MD_ArenaTemp scratch = MD_GetScratch(0, 0);
MD_String8 failure_reason = is_action_valid(scratch.arena, from, a); MD_String8 failure_reason = is_action_valid(scratch.arena, from, a);
if(failure_reason.size > 0) if(failure_reason.size > 0)
{ {
@ -1154,6 +1169,12 @@ void cause_action_side_effects(Entity *from, Action a)
assert(to); assert(to);
} }
if(a.kind == ACT_releases_sword_of_nazareth)
{
assert(from->npc_kind == NPC_Pile);
from->gave_away_sword = true;
}
if(a.kind == ACT_give_item) if(a.kind == ACT_give_item)
{ {
assert(a.argument.item_to_give != ITEM_invalid); assert(a.argument.item_to_give != ITEM_invalid);
@ -2189,6 +2210,16 @@ Quad quad_centered(Vec2 at, Vec2 size)
return to_return; return to_return;
} }
Quad quad_rotated_centered(Vec2 at, Vec2 size, float rotation)
{
Quad to_return = quad_centered(at, size);
for(int i = 0; i < 4; i++)
{
to_return.points[i] = AddV2(RotateV2(SubV2(to_return.points[i], at), rotation), at);
}
return to_return;
}
bool aabb_is_valid(AABB aabb) bool aabb_is_valid(AABB aabb)
{ {
Vec2 size_vec = SubV2(aabb.lower_right, aabb.upper_left); // negative in vertical direction Vec2 size_vec = SubV2(aabb.lower_right, aabb.upper_left); // negative in vertical direction
@ -4180,33 +4211,9 @@ void frame(void)
{ {
} // skelton combat and movement } // skelton combat and movement
} }
else if (it->npc_kind == NPC_Edeline) // npc processing functions go here
{
}
else if (it->npc_kind == NPC_TheKing)
{
}
else if (it->npc_kind == NPC_Red)
{
}
else if (it->npc_kind == NPC_Blue)
{
}
else if (it->npc_kind == NPC_Davis)
{
}
else if (it->npc_kind == NPC_TheBlacksmith)
{
}
else if (it->npc_kind == NPC_Bill)
{
}
else if (it->npc_kind == NPC_Jester)
{
}
else else
{ {
assert(false);
} }
if (it->damage >= entity_max_damage(it)) if (it->damage >= entity_max_damage(it))
@ -4732,6 +4739,17 @@ void frame(void)
} }
draw_animated_sprite((DrawnAnimatedSprite) { ANIM_knight_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), tint }); draw_animated_sprite((DrawnAnimatedSprite) { ANIM_knight_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), tint });
} }
else if(it->npc_kind == NPC_Pile)
{
DrawParams d = { true, quad_centered(it->pos, V2(TILE_SIZE, TILE_SIZE)), IMG(image_pile), WHITE, };
if(!it->gave_away_sword)
{
DrawParams d = { true, quad_rotated_centered(AddV2(it->pos, V2(0, 15.0f)), V2(TILE_SIZE, TILE_SIZE), -PI32*0.75f), IMG(image_sword), WHITE, };
draw_quad(d);
}
draw_shadow_for(d);
draw_quad(d);
}
else else
{ {
assert(false); assert(false);
@ -4800,11 +4818,7 @@ void frame(void)
if(cur->progress < 1.0f) if(cur->progress < 1.0f)
{ {
float radius = SWORD_SWIPE_RADIUS; float radius = SWORD_SWIPE_RADIUS;
Quad to_draw = quad_centered(cur->from, V2(radius, radius)); Quad to_draw = quad_rotated_centered(cur->from,V2(radius, radius), powf(cur->progress * 4.0f, 1.5f));
for(int i = 0; i < 4; i++)
{
to_draw.points[i] = AddV2(RotateV2(SubV2(to_draw.points[i], cur->from), powf(cur->progress * 4.0f, 1.5f)), cur->from);
}
draw_quad((DrawParams){true, to_draw, IMG(image_swipe), blendalpha(WHITE, 1.0f - cur->progress)}); draw_quad((DrawParams){true, to_draw, IMG(image_swipe), blendalpha(WHITE, 1.0f - cur->progress)});
} }
} }

@ -256,7 +256,7 @@ typedef struct Entity
#ifdef DESKTOP #ifdef DESKTOP
int times_talked_to; // for better mocked response string int times_talked_to; // for better mocked response string
#endif #endif
bool gave_away_sword;
BUFF(Memory, REMEMBERED_MEMORIES) memories; BUFF(Memory, REMEMBERED_MEMORIES) memories;
bool direction_of_spiral_pattern; bool direction_of_spiral_pattern;
float dialog_panel_opacity; float dialog_panel_opacity;
@ -340,6 +340,12 @@ void fill_available_actions(Entity *it, AvailableActions *a)
*a = (AvailableActions) { 0 }; *a = (AvailableActions) { 0 };
BUFF_APPEND(a, ACT_none); BUFF_APPEND(a, ACT_none);
if(it->npc_kind == NPC_Pile)
{
if(!it->gave_away_sword) BUFF_APPEND(a, ACT_releases_sword_of_nazareth);
}
else
{
if(it->held_items.cur_index > 0) if(it->held_items.cur_index > 0)
{ {
BUFF_APPEND(a, ACT_give_item); BUFF_APPEND(a, ACT_give_item);
@ -364,6 +370,7 @@ void fill_available_actions(Entity *it, AvailableActions *a)
{ {
BUFF_APPEND(a, ACT_stops_fighting_player); BUFF_APPEND(a, ACT_stops_fighting_player);
} }
}
} }
#define MAX_ENTITIES 128 #define MAX_ENTITIES 128

Loading…
Cancel
Save